Vue router-link param undefined in nested loop - loops

I have a loop inside another loop.
The videos.id is undefined in the <router-link> but is rendered just fine otherwise..
<ul>
<li v-for="category in categories" :key="category.id">
{{category.name}}
<div v-for="videos in category.videos" :key="videos.id">
<router-link v-bind:to="/video-player/ + videos.id"> {{videos.id}} {{videos.name}}</router-link>
</div>
</li>
</ul>

Based on your codepen: https://codepen.io/cwerner/pen/mdyjLBv
It is showing videos.id as undefined because this data doesn't exist:
{
id: 1,
name: "Category",
videos: [
{
name: "Video1"
},
{
name: "Video 2",
}
],
}
There is only an id for category, so you must add id's in the video objects too:
{
id: 1,
name: "Category",
videos: [
{
name: "Video1",
id: 1
},
{
name: "Video 2",
id: 2
}
],
}

Content of binded property has to be valid JS expression. /video-player/ + videos.id is not valid JS expression. Change it to v-bind:to="'/video-player/' + videos.id"

Related

how to get data from an array in a json?

how can I get the information from this json to paint them in angular 10
{
"countries": [
{
"id": 1,
"name": "United States"
},
{
"id": 2,
"name": "India"
}
],
"states": [
{
"id": 1,
"countryId": 1,
"name": "Alabama"
},
{
"id": 2,
"countryId": 1,
"name": "Alaska"
}
]
}
for normal jsons I used this one, but that jeson has 2 arrays and it won't let me
return this.http.get<Country[]>("./assets/data.json");
Error trying to diff '[object Object]'. Only arrays and iterables are allowed
<!-- html -->
<div *ngFor="let item of countri">
{{item.id}}
</div>
model
export interface Country {
id: number;
name: string;
}
and my subscribe
countri: Country[] = [];
this.countriesService.getCountries().subscribe(
countri => {
this.countri = countri;
console.log(countri);
},
err => console.log(err)
);
Use any.
1st way:
return this.http.get<any>("./assets/data.json");
2nd way define an proper interface for your data.
export interface IRequest {
countries: ICourtry[],
states: IState[]
}
export interface ICourtry{
id:number;
name: string;
}
export interface IState{
id:number;
name: string;
countryId: number;
}
return this.http.get<IRequest>("./assets/data.json");
This mentioned error(Error trying to diff '[object Object]') are because you are using this json somewhere in your template but it has no values. Hope it will fix it or provide the template code also.
Error trying to diff '[object Object]'. Only arrays and iterables are allowed , this error usually comes when you try to iterate through ngFor with an Object instead of an Array.
If you are using ngFor,
list.component.ts
data={
"countries": [
{
"id": 1,
"name": "United States"
},
{
"id": 2,
"name": "India"
}
],
"states": [
{
"id": 1,
"countryId": 1,
"name": "Alabama"
},
{
"id": 2,
"countryId": 1,
"name": "Alaska"
}
]
}
list.component.html
<ul>
<li *ngFor="let item of data.countries">
{{item.name}}
</li>
</ul>
or
<ul>
<li *ngFor="let item of data.states">
{{item.name}}
</li>
As the error suggests, you are most likely trying to iterate over an object rather than an array. Also, since the data you fetch is asynchronous you may make use of the following code to avoid any errors. It makes use of the async pipe along with the safe(?) operator.
.ts
jsonData;
ngOnInit() {
this.jsonData = this.http.get('./assets/data.json');
}
template
<div *ngFor="let country of (jsonData | async)?.countries">
{{ country | json}}
</div>
<div *ngFor="let state of (jsonData | async)?.states">
{{ state | json}}
</div>

Dispaly object of array values in angular 2 using Ngfor

I have a array of object values.i am using a group by method to group the values based on type.it gives a object of array values.i struggle to how to display the values using Ngfor in angular 2.
i have a following structure value.
{
[
{
id:1
body:"value1"
type:"name"
},
{
id:2
body:"value1"
type:"id"
}
],
[
{
id:3
body:"value1"
type:"name"
},
{
id:4
body:"value1"
type:"id"
},
{
id:5
body:"value1"
type:"name"
}
],
[
{
id:6
body:"value1"
type:"id"
},
{
id:7
body:"value1"
type:"fname"
},
{
id:8
body:"value1"
type:"fname"
}
]
}
And my html code is.
<div *ngFor="let value of result">
{{value.body}}
</div>
ngFor only works on Array element. Also your current JSON seems to invalid. Though You can easily flatten the arrays into single array and use ngFor to render it on DOM
<div *ngFor="let value of flattenArray">
{{value.body}}
</div>
Component
flattenArray = [];
//after retrieving result, create flatten array.
for(let value of result){
this.flattenArray.conact(value);
}
what you have is not an array of objects, it's even not a JSON (check it with https://jsonlint.com/),
when you replace first {} with [], (and add comas, ofcourse!) all will works fine, here is valid json:
[
[
{
id:1,
body:"value1",
type:"name"
},
{
id:2,
body:"value1",
type:"id"
}
],
[
{
id:3,
body:"value1",
type:"name"
},
{
id:4,
body:"value1",
type:"id"
},
{
id:5,
body:"value1",
type:"name"
}
]
]
and then in angular view:
<div *ngFor="let items of result">
<div *ngFor="let value of items">
{{value.body}}
</div>
</div>
Thanks for everyone response.i got a solution for the question.
let value = _.groupBy(data, "type");
for (let key in value) {
content.push({ key: key, value: value[key] });
}
and my html is
<div *ngFor="let keys of content">
<div *ngFor="let value of keys.value">
{{value.body}}
</div>
</div>

ng-repeat show subtitle for first type of item

I have a list of objects that have all the same fields except for its type. I would like to show a subtitle in the ng-repeat right before this type of item is rendered. Right now I have x ng-repeats for x types of items and its becoming unmanageable. The blocks are all the same except for the subtitle. Assume that the scope array doesn't have types scattered, they're subdivided with its type. For example, when rendered I would like to show this.
Rendered
Cats
cat 1
cat 2
cat 3
Dogs
dog 1
dog 2
dog 3
Lizards
lizard 1
lizard 2
lizard 3
Model
$scope.animals = [
{ name: "cat 1", type: "cat" },
{ name: "cat 2", type: "cat" },
{ name: "cat 3", type: "cat" },
{ name: "dog 1", type: "dog" },
{ name: "dog 2", type: "dog" },
{ name: "dog 3", type: "dog" },
{ name: "lizard 1", type: "lizard" },
{ name: "lizard 2", type: "lizard" },
{ name: "lizard 3", type: "lizard" }
];
View
<div ng-repeat="animal in animals">
<!-- if first animal type appearing show subtitle -->
{{animal.name}}
</div>
I do not want to structure my data this way which I'm doing now and rendering redundant ng-repeats.
Model
$scope.cats = [
...
];
$scope.dogs = [
...
];
$scope.lizards = [
...
];
View
<h2>Cats</h2>
<div ng-repeat="cat in cats">
{{cat.name}}
</div>
<h2>Dogs</h2>
<div ng-repeat="dog in dogs">
<h2>Dogs</h2>
{{dog.name}}
</div>
<h2>Lizards</h2>
<div ng-repeat="lizard in lizards">
{{lizard.name}}
</div>
Thanks in advance!
You need to check if the type is different from the previous type. You can get this item using $index - 1
<div ng-repeat="animal in animals">
<h1 ng-if="animal.type != animals[$index - 1].type">
{{ animal.type }}
</h1>
{{animal.name}}
</div>
Try to access the previous element of your ng-repeatloop and compare its type to the type of the current element. If the type is different, you have to show your subtitle.
See this question for info how to obtain the previous element.

AngularJS push to array parse in view

I have a controller where I declare the model like this:
$scope.Model =[];
after I make a rest call and the result I push it to the model:
$scope.Model.push(results.data);
The data returned can be in different length and size:
Name
Email
Items
Item 1
Item 2
Item n
Roles
Role 1
Role 2
Role n
What is the best practice of handling this with arrays in AngularJS and using ng-repeat in view in order to show the data?
Should I declare my array like this:
$scope.Model =[];
and push the results:
$scope.Model.push(results.data);
or like this:
$scope.Model =[{
Name: '',
Email: '',
Items: [{
Id: '',
Name: '',
Price: ''
}],
Roles: [{
Id: '',
Name: ''
}],
}];
and asign the results:
$scope.Model = results.data;
It is based on your response and scenarios. but ng-repeat expects Array or Array list.
1) Array
Example 1 (plain array response)
$scope.names= ["Apple", "Banana", "Orange"];
<ul>
<li ng-repeat="x in names">
{{ x }}
</li>
</ul>
Example 2 (Object response that has array)
$scope.names= {
"fruits": ["Apple", "Banana", "Orange"]
};
<ul>
<li ng-repeat="x in names.fruits">
{{ x }}
</li>
</ul>
2) Array List
Example 1 (plain array list response)
$scope.names = [{
"id": "1",
"name": "Asik"
},
{
"id": "1",
"name": "John"
},
{
"id": "1",
"name": "Smith"
}];
<ul>
<li ng-repeat="x in names">
id:{{ x.id }}, name:{{ x.name }}
</li>
</ul>
Example 2 (Object response that has array list)
$scope.names = {
"success": "true",
"items": [{
"id": "1",
"name": "Asik"
},
{
"id": "1",
"name": "John"
},
{
"id": "1",
"name": "Smith"
}]
};
<ul>
<li ng-repeat="x in names.items">
id:{{ x.id }}, name:{{ x.name }}
</li>
</ul>
Basically, service/ajax response comes as Array or Array list. So you don't need to do the following steps.
$scope.Model =[];
$scope.Model.push(results.data);
But the above case comes in some situation (for eg: merging 2 service/ajax responses )
I have used the following:
angular.copy(results.data, $scope.Model)
This will actually copy the results from the rest servicve into my model without having to declare each property of the model.

Advanced filtering with AngularJS

I'm looking to filter the following list with AngularJS by both category and location. The difficulty I'm having is being able to properly nest the results beneath their respective categories (see below) after the filtering has occurred.
var jobs = [
{
title: "Software Engineer",
category: "Engineering",
location: "New York"
},
{
title: "Web Developer",
category: "Engineering",
location: "Chicago"
},
{
title: "UX Designer",
category: "Design",
location: "New York"
}
]
This is the desired output (also note the alphabetically ordered categories):
Design
UX Designer
Engineering
Software Engineer
Web Developer
Any help would be much appreciated. Thanks!
Here is a working example with your data on plnkr using the filter solution from AngularJS Group By Directive without External Dependencies:
http://plnkr.co/edit/w5UJUN?p=preview
Do you have something like this in your mind:
<b>Design</b>
<ul>
<li ng-repeat="job in jobs | filter: { category:'Design'}">
{{job.title}}
</li>
</ul>
<b>Engineering</b>
<ul>
<li ng-repeat="job in jobs | filter: { category:'Engineering'}">
{{job.title}}
</li>
</ul>
There is working JSFiddle.
I would re-structure my JSON as follows:
$scope.parsedJobs = [];
angular.forEach($scope.jobs, function(value, key) {
var j = $scope.parsedJobs.filter(function(element) {
return element.category == value.category;
});
if (j.length > 0) {
$scope.parsedJobs[0].elements.push({
title: value.title,
location: value.location
});
} else {
$scope.parsedJobs.push({
category: value.category,
elements: [{
title: value.title,
location: value.location
}]
});
}
});
Fiddle

Resources