Angular ng-repeat - how to concatenate or combine data from different arrays
I am trying to concatenate / concatenate two arrays in angular ng-repeat.
Simple example book / author where I want to print the titles of the books with the appropriate author name.
Books are in one array, authors in another.
How do I join the data in this example?
JSFiddle: 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>
source to share
EDIT: Requires at least AngularJS 1.2
I would use an angle filter:
<div>
Authors name: {{authors[$index].name}}
</div>
in
<div>
Authors name: {{(authors | filter:{'id': book.id_author}:true)[0].name}}
</div>
What we're doing here is taking an array authors
and filter
expressing it 'id': book.id_author
, and we are taking the .name
first element of this filtering ( [0]
).
Just in case, you can check if you actually have the author in your array:
<div>
Authors name: {{(authors | filter:{'id': book.id_author}:true)
? (authors | filter:{'id': book.id_author}:true)[0].name
: 'Unknown'}}
</div>
Regards
PS ( EDIT ): fiddle with angular 1.2.6 -> http://jsfiddle.net/gqqv9k38/1/
source to share
- You can create your own
findAuthor
method - Use the usual
filter
sstrict
to select the exact author you wantid
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. findAuthor metod</h4>
<div ng-app='app', ng-controller='ctrl'>
<div ng-repeat="book in books">
<div>Book title: {{book.name}}</div>
<div>Authors name: {{findAuthor(book.id_author).name}}</div>
<hr>
</div>
<h4>2. With help of filter</h4>
<div ng-repeat="book in books">
<div>Book title: {{book.name}}</div>
<div>Authors name: {{(authors | filter: {'id': book.id_author}: strict)[0].name}}</div>
<hr>
</div>
</div>
source to share
This is the most optimal solution for your problem.
Place the below code in 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'];
}
}
}
And update the view file with below code:
<div ng-controller="MyCtrl">
<div ng-repeat="book in entries">
<div>Book title: {{book.name}}</div>
<div>Authors name: {{book.author_name}}</div>
<hr>
</div>
</div>
source to share
You can do the following:
<div ng-repeat="book in books">
<div>Book title: {{book.name}}</div>
<div>Authors name: {{getAuthorName(book.id_author)}}</div>
</div>
in js:
$scope.getAuthorName(id) {
var name;
name = $scope.authors.find(function(author) {
if(author.id_author === id) {
return author.name;
}
})
return name;
}
Hope it helps :)
source to share
create a function and filter the name according to id
$scope.getName = function(obj){
return $scope.authors.find(o=>{
if(o.id == obj.id_author){return o }
})
}
call it like this
<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>
source to share
You can simply compare the values and add them to the model books
. This can be done as shown 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>
source to share
Here is your answer, with a demo :) .. your author array should be sorted in my case;)
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>Authors name: {{authors[book.id_author -1].name}}</div>
<hr>
</div>
</div>
</html>
source to share