Reputation: 187
I'm trying to join/combine two arrays in angular ng-repeat.
Simple example book/author where I want to print book titles with coresponding author name.
Books are in one array, authors in another.
How to join 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>
Upvotes: 3
Views: 1794
Reputation: 424
EDIT: At least AngularJS 1.2 is required
I would use angulars filter:
<div>
Authors name: {{authors[$index].name}}
</div>
to:
<div>
Authors name: {{(authors | filter:{'id': book.id_author}:true)[0].name}}
</div>
What we are doing here is taking the array authors
and filter
it by the expression 'id': book.id_author
and we take the .name
of the first element of this filtering ([0]
).
Just in case you could 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>
Best regards
PS (EDIT): fiddle with angular 1.2.6 -> http://jsfiddle.net/gqqv9k38/1/
Upvotes: 3
Reputation: 13488
findAuthor
methodfilter
with strict
to select exactly needed author id
instead of similar 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>
Upvotes: 2
Reputation: 956
Here is your answer, with demo :) ..your author array must 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>
Upvotes: 0
Reputation: 540
This is the most optimized solution for your problem.
Put 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 your 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>
Upvotes: 2
Reputation: 10198
You can merge both JSON data into new array
var newArray= authors.map(x => Object.assign(x, books.find(y => y.id == x.id)));
Upvotes: 0
Reputation: 18923
You can simply compare the values and add it to the books
model. It 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>
Upvotes: 0
Reputation: 41447
create the 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>
Upvotes: 0
Reputation: 2668
You can do like this:
<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 this helps :)
Upvotes: 0