Unleashing the power of Angular's ng-repeat: merging data across multiple arrays

Is it possible to merge two arrays in Angular's ng-repeat functionality?

For instance, let's say we have arrays containing book titles and author names. How can we display the book titles along with their corresponding author names?

One array holds the book data, while another contains the author information.

What is the best way to combine the data in this scenario?

Check out the JSFiddle example: http://jsfiddle.net/1jxsh0x3/

var myApp = angular.module('myApp', []);

function MyCtrl($scope) {

  $scope.authors = [{
    id: "1",
    name: "John"
  }, {
    id: "2",
    name: "Peter"
  }, {
    id: "3",
    name: "Mark"
  }];
  
  $scope.books = [{
    id: "1",
    id_author: "3",
    name: "Book Lorem"
  }, {
    id: "2",
    id_author: "1",
    name: "Book Ipsum"
  }, {
    id: "3",
    id_author: "1",
    name: "Book Dark"
  }];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<div ng-controller="MyCtrl">
  <div ng-repeat="book in books">
    <div>Book title: {{book.name}}</div>
    <div>Authors name: {{authors[$index].name}}</div>
    <hr>
  </div>
</div>

Answer №1

UPDATE: AngularJS 1.2 or later version is necessary

My recommendation would be to utilize the angulars filter:

<div>
    Author's name: {{authors[$index].name}}
</div>

and modify it to:

<div>
    Author's name: {{(authors | filter:{'id': book.id_author}:true)[0].name}}
</div>

Essentially, what we are implementing is filtering the array authors based on the expression 'id': book.id_author and then extracting the .name of the first element after filtering ([0]).

As a precaution, you can verify if the author exists in your array:

<div>
    Author's name: {{(authors | filter:{'id': book.id_author}:true) 
                     ? (authors | filter:{'id': book.id_author}:true)[0].name
                     : 'Unknown'}}
</div>

Warm regards

PS (UPDATE): test it out with angular 1.2.6 -> http://jsfiddle.net/abcd1234/1/

Answer №2

This is the most efficient solution tailored to address your specific issue.

Insert the code snippet below into your controller file -

$scope.entries = [];
angular.forEach($scope.books,function(entry) {
    var author_name;
    var searchField = "id";
    var searchVal = entry.id_author;
    author_name = getAuthorName(searchField,searchVal,$scope.authors)
    $scope.SubInformation['author_name'] = author_name;
    $scope.entries.push(angular.extend(entry,$scope.SubInformation));   
});

function getAuthorName(searchField,searchVal,authors){
    for (var i=0 ; i < authors.length ; i++)
    {
        if (authors[i][searchField] == searchVal) {
            return authors[i]['name'];
        }
    }
}

Also, update your view file with the following code snippet:

<div ng-controller="MyCtrl">
  <div ng-repeat="book in entries">
    <div>Book Title: {{book.name}}</div>
    <div>Author's Name: {{book.author_name}}</div>
    <hr>
  </div>
</div>    

Answer №3

  1. To enhance your functionality, consider creating a personalized findAuthor method
  2. Opt for the standard filter function with strict option to precisely pinpoint the required author id instead of a similar one

angular.module('app',[])
.controller('ctrl', function($scope){

  $scope.authors = [{
    id: "1",
    name: "John"
  }, {
    id: "11",
    name: "Peter"
  }, {
    id: "3",
    name: "Mark"
  }];
  
  $scope.books = [{
    id: "1",
    id_author: "3",
    name: "Book Lorem"
  }, {
    id: "2",
    id_author: "1",
    name: "Book Ipsum"
  }, {
    id: "3",
    id_author: "1",
    name: "Book Dark"
  }];
  
    
  $scope.findAuthor = function(id){
    return $scope.authors.find(function(x){
    return x.id == id
   })};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<h4>1. Custom findAuthor Method</h4>
<div ng-app='app', ng-controller='ctrl'>  
  <div ng-repeat="book in books">
      <div>Title of Book: {{book.name}}</div>
      <div>Name of Author: {{findAuthor(book.id_author).name}}</div>
      <hr>
  </div>
  
<h4>2. Utilizing Filter Function</h4>    
  <div ng-repeat="book in books">
    <div>Title of Book: {{book.name}}</div>
    <div>Name of Author: {{(authors | filter: {'id': book.id_author}: strict)[0].name}}</div>
    <hr>
  </div>

</div>

Answer №4

To achieve the desired outcome, follow these steps:

<div ng-repeat="book in books">
    <div>Book title: {{book.name}}</div>
    <div>Authors name: {{getAuthorName(book.id_author)}}</div>
</div>

Here's how to implement it in JavaScript:

$scope.getAuthorName(id) {
    var name;
    name = $scope.authors.find(function(author) {
        if(author.id_author === id) {
            return author.name;
        }
    }) 
    return name;
}

Give this a try and see if it works for you :)

Answer №5

design a function to filter and retrieve names based on ID

$scope.getName = function(obj){

    return $scope.authors.find(o=>{
      if(o.id == obj.id_author){return o }
    })
  }

implement it as shown below

<div ng-controller="MyCtrl">
  <div ng-repeat="book in books">
    <div>Book title: {{book.name}}</div>
    <div>Authors name: {{getName(book).name}}</div>
    <hr>
  </div>
</div>

Check out the Demo

Answer №6

To easily compare the values and incorporate them into the books model, you can follow the steps outlined below:

var myApp = angular.module('myApp', []);

    function MyCtrl($scope) {

      $scope.authors = [{
        id: "1",
        name: "John"
      }, {
        id: "2",
        name: "Peter"
      }, {
        id: "3",
        name: "Mark"
      }];
      
      $scope.books = [{
        id: "1",
        id_author: "3",
        name: "Book Lorem"
      }, {
        id: "2",
        id_author: "1",
        name: "Book Ipsum"
      }, {
        id: "3",
        id_author: "1",
        name: "Book Dark"
      }];
      
      for(var i = 0; i < $scope.books.length; i++){
          var id = $scope.books[i].id_author;
          for(var j = 0; j < $scope.authors.length; j++){
              if($scope.authors[j].id ==  $scope.books[i].id_author ){
               $scope.books[i].authorName =  $scope.authors[j].name;
              }
          }
      }
      
   }

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app = "myApp">
    <div ng-controller="MyCtrl">
        <div ng-repeat="book in books">
            <div>Book title: {{book.name}}</div>
            <div>Authors name: {{book.authorName}}</div>
            <hr>
        </div>
    </div>
</html>

Answer №7

Combining JSON data from two sources can be done easily by creating a new array.

const mergedArray = authors.map(author => Object.assign(author, books.find(book => book.id === author.id)));

Answer №8

Here is the solution for you, complete with a demo :) ..just make sure your author array is sorted in my particular instance ;)

var myApp = angular.module('myApp', []);

function MyCtrl($scope) {

  $scope.authors = [{
    id: "1",
    name: "John"
  }, {
    id: "2",
    name: "Peter"
  }, {
    id: "3",
    name: "Mark"
  }];

  $scope.books = [{
    id: "1",
    id_author: "3",
    name: "Book Lorem"
  }, {
    id: "2",
    id_author: "1",
    name: "Book Ipsum"
  }, {
    id: "3",
    id_author: "1",
    name: "Book Dark"
  }];

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="myApp">
<div ng-controller="MyCtrl">
  <div ng-repeat="book in books">
    <div>Book Title: {{book.name}}</div>
    <div>Author's Name: {{authors[book.id_author -1].name}}</div>
    <hr>
  </div>
</div>

</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

a single button with dual functionalities

I am new to the development field and have a question about jQuery. I want a single button to perform two different actions. For example, let's say we have a button labeled Pause/Resume. When I click on the button, it should first display "Pause", and ...

Vue.js / Nginx / Node.js - Error 413: Payload Too Big

My frontend is built using Vue.js and is hosted on an nginx server in production. Here's a snippet of my nginx.conf configuration: server { listen 80; server_name localhost; root /usr/share ...

Developing a web application using Yeoman generator to scaffold an AngularJS frontend with an Express server

I am currently experimenting with using ExpressJS alongside the pre-built version of Angular provided by the Yeoman generator for AngularJS. I have opted to utilize the scaffolding created by the Yeoman Team rather than relying on frameworks like angular-f ...

Why isn't my content appearing correctly on different pages?

This ecommerce site is my very first project using React. I have created pages for Contact, Login, and more. The footer and other components display correctly on the home page, but when navigating to other pages, the content appears shortened. For referen ...

Is it advisable to combine ng-change with ng-blur in AngularJS?

Seeking clarification on the correct usage of AngularJS's ng-change and ng-blur from an expert. Specifically, when updating a form value. In the code snippet below, I have a dropdown where I would like to trigger overrideBusinessDec() when the user ...

Trouble with Bootstrap Modal not closing properly in Chrome and Safari

ISSUE: I'm facing a problem where clicking on the X (font awesome icon) doesn't close the modal popup as expected. https://i.sstatic.net/yXnwA.jpg LIMITED FUNCTIONALITY ON CERTAIN BROWSERS: Currently, the X button for closing the modal works o ...

Step-by-step guide on utilizing filesystem I/O to upload a file in a Mean app

I have encountered an issue while using the fs module to upload a file in my web application. Despite the console showing that the file has been successfully saved to the specified location, the file itself does not appear there. Below is the code snippet ...

Instructions on implementing getJSON in this code

I recently set up a chained select box with JSON data to populate options, using this Fiddle. While the data is hardcoded for now, I am looking to load it using the $.getJSON() method. However, despite my efforts, I haven't been able to get the code r ...

Continue looping in AngularJS starting from a specific index

I'm trying to make my AngularJS loop function properly. Currently, it's working fine, but I want to either add more items to it or pick up where it left off from a specific index in the array... **Sample HTML code:** <div ng-repeat="company ...

What steps can I take to completely remove JavaScript from an HTML document?

To eliminate the <script> tags in the HTML, I can utilize regex just like this $html = preg_replace('#<script(.*?)>(.*?)</script>#is','', $html); While this approach works well, dealing with inline JavaScript require ...

The clingy navigation bar hinders smooth scrolling to the content

My website has an image where users can click on elements to scroll down to text. However, I'm facing a problem because there is a sticky menu at the top of my website. How can I ensure that the scrolling works correctly with the sticky menu included? ...

Executing a function from index.html that continuously loops without any limits

I'm currently working on creating a function that displays specific HTML content only to users with certain roles. Here are the functions I've set up for this: nodejs/server.js app.get('/api/isadmin', ensureAuthenticated, function (re ...

grabbing data from different domains using jQuery

I attempted to implement cross-domain AJAX examples, but unfortunately, it did not function as expected. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr"> <head> <meta http-equiv="Content-Type" content="text/ht ...

When trying to integrate Angular.ts with Electron, an error message occurs: "SyntaxError: Cannot use import statement

Upon installing Electron on a new Angular app, I encountered an error when running electron. The app is written in TypeScript. The error message displayed was: import { enableProdMode } from '@angular/core'; ^^^^^^ SyntaxError: Cannot use impor ...

I am looking to showcase a series of icons linked together by connecting lines

I have successfully designed the layout and added icons, but I am facing difficulty in creating connecting lines between them. I attempted to utilize CSS borders and pseudo-elements, yet I cannot achieve the desired outcome. If anyone could offer a CSS-ba ...

Puppeteer: Navigate to a specific page number

I'm encountering an issue with a table and page numbers as links, such as: 1, 2, 3, 4 etc… -> each number is a link. Attempted to create a loop to click on different page numbers. On the first iteration, I can reach page 2. However, on the secon ...

Issue with Javascript Date and Time Validation

My application includes code that is supposed to display HTML pages based on today's date and the time of day (morning, afternoon, or evening). However, it seems like there is an issue with how the time is being checked. Currently, at 2:53pm, only the ...

Guidance on establishing an Array data type for a field in GraphQL Type declarations

Hey there! Currently, I'm working on my Nodejs project and facing a little dilemma. Specifically, I am trying to specify the type for graphQL in the code snippet below. However, I seem to be struggling with defining a field that should have a Javascri ...

Look into HTML and JavaScript problems specific to IOS devices

I have encountered some HTML markup and JavaScript functionality issues on my web-app that seem to only occur on iPad and iPhone. Unfortunately, I do not have access to any iOS devices to debug these problems. How can I replicate and troubleshoot these i ...

What steps do I take to resolve the error message "npm ERR! code1"?

While exploring some open-source projects to learn, I encountered an error after running npm install in the terminal to download packages. It seems that there are some missing packages, and I couldn't figure out the root cause of the error. Initially, ...