I am new to Ionic and I am trying to display nested list. I am using JSON response from the server to get all the values. This is my server response.
{
"addonCategories": [
{
"id": 24,
"name": "Cooking type",
"parent_id": 0,
"product_category": 10,
"selection": "single",
"type": "other",
"order": null,
"shows_selection": true,
"selection_type": true,
"direct_pricing": false,
"is_size": false,
"addonItems": [
{
"id": 725,
"name": "Lightly Done",
"product_id": 0,
"addon_category_id": 24,
"price": 0,
"image": "",
"attribute": null,
"main_category_id": 24,
"half_image": null,
"full_image": null,
"order": null,
"large_price": "",
"description": null,
"default_sauce": 0,
"restaurants_id": 0
},
{
"id": 723,
"name": "Regular",
"product_id": 0,
"addon_category_id": 24,
"price": 0,
"image": "",
"attribute": null,
"main_category_id": 24,
"half_image": null,
"full_image": null,
"order": null,
"large_price": "",
"description": null,
"default_sauce": 0,
"restaurants_id": 0
},
{
"id": 724,
"name": "Well Done",
"product_id": 0,
"addon_category_id": 24,
"price": 0,
"image": "",
"attribute": null,
"main_category_id": 24,
"half_image": null,
"full_image": null,
"order": null,
"large_price": "",
"description": null,
"default_sauce": 0,
"restaurants_id": 0
}
]
}
]
}
I am using following HTML code to display nested list with checkbox selection.
<ion-list class="setting-content">
<ion-list-header *ngFor="let item of (addonDetail | async)?.addonCategories" no-lines>{{item.name}}
<ion-item-group class="fst-group">
<ion-item *ngFor="let item1 of item.addonItems" no-lines>
<ion-label >{{item1.name}}</ion-label>
<ion-checkbox (click)="clickAddon(item1)" item-right></ion-checkbox>
</ion-item>
</ion-item-group>
</ion-list-header>
</ion-list>
So how can I get the names from inner JSON array addonItems?
When I run the code it gives me the names from main array (addonCategories) but not from the inner one (addonItems).
The issue is the structure of your HTML template - in short, when you have an ion-list-header, it attempts to render the text for that header in an ion-label. The presence of your nested ion-label (within your ion-item) thus breaks the template.
Instead, and per the Ionic documentation here, your ion-list-header should not contain any child ion-item elements: https://ionicframework.com/docs/api/components/item/Item/#advanced
If instead you restructure your HTML template like this, it will work:
<ion-list class="setting-content">
<ng-container *ngFor="let item of addonCategories">
<ion-list-header no-lines>{{item.name}}</ion-list-header>
<ion-item-group class="fst-group">
<ion-item *ngFor="let addOn of item.addonItems" no-lines>
<ion-label>{{addOn.name}}</ion-label>
<ion-checkbox (click)="clickAddon(addOn)" item-right></ion-checkbox>
</ion-item>
</ion-item-group>
</ng-container>
</ion-list>
Notice on line 3 that the ion-list-header is opened & closed.
Because of the need for nested *ngFor directives - which I'm guessing is why you tried to embed your ion-item elements in the header - I've used the ng-container instead. This way, you can still iterate through each "header" item's array of nested addonItems.
Working Plnkr here: https://embed.plnkr.co/RSd1MdmajLxpdZmTHk8J/
Related
I have made a component that is iterated by an array. Then the data inside of that array is being pushed into each iterated component. I am able to display data from the array, but unable to display data from an array that is inside of the array.
Here is an example of the data:
[
{
"questionArray": [
{
"questionText": "How many cats do you have? ",
"questionId": "",
"questionControlTypeId": "",
"questionSequence": "",
"imageUrl": null,
"quizId": "",
"isEditing": false,
"questionAnswers": [
{
"answer": "1",
"correctAnswer": false,
"questionAnswerId": "",
"questionId": "",
"sortOrder": ""
},
{
"answer": "3",
"correctAnswer": false,
"questionAnswerId": null,
"questionId": null,
"sortOrder": null
},
{
"answer": "4",
"correctAnswer": false,
"questionAnswerId": null,
"questionId": null,
"sortOrder": null
},
{
"answer": "5",
"correctAnswer": false,
"questionAnswerId": null,
"questionId": null,
"sortOrder": null
}
]
}
],
"id": 1
} ]
There is more than one object of this data.
Here's what I'm attempting to do with it.
<div *ngFor="let example of exampleArray$">
<div *ngFor="let ex of example.nestedData">
<example-component
exampleQuestion="{{ex.questionText}}"
exampleAnswer="{{ex.questionAnswers}}"
></example-component>
</div>
</div>
Then I'm using #Input in my TS file for "example-component" to get that data and use it in the HTML.
#Input() exampleQuestion;
#Input() exampleAnswer;
I'm using {{questionText}} to display my text, and it's working just fine.
The issue is with "questionAnswers". Which itself is an array, and not only is it an array, it's also going to be used on a reactive form that has dynamic controls.
<div *ngFor="let htmlexample of questionAnswers">
--this would be where my dynamic input field is--
<div>
However, instead of getting back multiple fields, I am getting this error:
ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'string'. NgFor only supports binding to Iterables such as Arrays.
I am also getting [object Object] in my console.logs.
My console.log of my observable (which is being maintained by BehaviorSubject) is logging the array appropriately.
Thank you in advance for any insight on this issue.
I don't think you need interpolation {{ }} and you should use property binding [ ] to bind the exampleQuestion and exampleAnswer to ex.questionText and ex.questionAnswers respectively. Try
<example-component
[exampleQuestion]="ex.questionText"
[exampleAnswer]="ex.questionAnswers"
></example-component>
Then inside example-component:
<div *ngFor="let htmlexample of exampleAnswer">
--this would be where my dynamic input field is--
<div>
Source: https://angular.io/guide/inputs-outputs#configuring-the-parent-component
Here is my JSON data I want to print the "4th January 2018" as list header and description as the content of the list. How can I use the *ngFor this data
when i use *ngFor="let item of timeline data"
I got an error
cannot find a differ supporting object '[object object]' of type 'object'. ngfor only supports binding to iterables such as arrays
Following is the data:
{
"msg": "All Timeline Data",
"data": {
"4th January 2018": [
{
"id": 294,
"description": "1st data",
"taken_on": "4th January 2018",
"status": "active",
"created_at": "2018-01-04 06:54:06",
"updated_at": "2018-01-04 06:54:06",
"deleted_at": null
},
"id": 295,
"description": "2nd data",
"taken_on": "4th January 2018",
"status": "active",
"created_at": "2018-01-04 06:54:06",
"updated_at": "2018-01-04 06:54:06",
"deleted_at": null
}
],
"5th January 2018": [
{
"id": 296,
"description": "3rd data",
"taken_on": "5th January 2018",
"status": "active",
"created_at": "2018-01-05 06:54:06",
"updated_at": "2018-01-05 06:54:06",
"deleted_at": null
}
]
}
}
Your "data" in not an array, it's an object.
If you replace
"data": {
with
"data": [
you will be able to iterate over dates.
Also, you seem to be missing { before the second item on your '"4th January 2018":' array.
If you really need to iterate over object properties, you could do something like this.
Component:
objectKeys = Object.keys;
Template:
<div *ngFor="let key of objectKeys(timeline.data)"> {{key + ' ' + timeline.data[key]}} </div>
convert your Object into array and then use it in *ngFor
here is working live demo
here is useful like Angular 2 ngFor— Not only for Arrays
Perhaps try adding the elvis operator. ?
The output below should be 294.
Also, as pointed out "data" is not an array, it is an object.
<ion-list>
<ion-item *ngFor="let item of timeline?.data?.4th January 2018>
<p>{{item.id}}</p>
</ion-item>
</ion-list>
I'm creating a laravel application and I'm trying to access a child object's properties in my view using Angular. I can get the whole data in my view (including child objects), but I'm having trouble when trying to display it using Angular.
controller:
public function index(Request $request)
$lang = $request->input('lang') ?? 'pt';
$interestTranslations = Interest::with([
'interesttranslations' => function($query) use ($lang) {
$query->where('languageCode', $lang);
}
])->get()->toArray();
return ['translatedInterests' => $interestTranslations];
}
}
js file:
app..controller("Interests", function ($scope, $rootScope, HobbiesService) {
var lang = $rootScope.lang;
HobbiesService.newData(lang).then(function (response) {
$rootScope.interests = response["data"].translatedInterests;
});
})
html file (interest.interesttranslations works but interest.interesttranslations.name_or_other_property doesn't):
<p style="color: white;">{{interests}}</p> <!-- this shows the whole json datam including the child objects-->
<div class="no-padding owl-carousel" id="hobbies-container" ng-controller="Interests">
<div ng-repeat="interest in interests">
<img src="/img/about/{{ interest.imageName }}" alt="{{ interest.imageName }}" /> <!--this works-->
<p style="color: white;">{{ interest.interesttranslations.name }}</p> <!--this doesn't work-->
</div>
</div>
json displayed in my view when using {{ interests }}:
[{
"id": 1,
"applicant_id": 1,
"imageName": "friends.png",
"created_at": null,
"updated_at": null,
"interesttranslations": [{
"interest_id": 1,
"languageCode": "pt",
"name": "explorar com amigos",
"created_at": null,
"updated_at": null
}]
}, {
"id": 2,
"applicant_id": 1,
"imageName": "world.png",
"created_at": null,
"updated_at": null,
"interesttranslations": [{
"interest_id": 2,
"languageCode": "pt",
"name": "viajar",
"created_at": null,
"updated_at": null
}]
},
{
"id": 3,
"applicant_id": 1,
"imageName": "tv-shows.png",
"created_at": null,
"updated_at": null,
"interesttranslations": [{
"interest_id": 3,
"languageCode": "pt",
"name": "séries televisivas",
"created_at": null,
"updated_at": null
}]
}
]
Thanks in advance!
The property interesttranslations is an array, not an object.
In the view try
{{ interest.interesttranslations[0].name }}
Or use an inner ng-repeat to iterate that array
<p ng-repeat="item in interest.interesttranslations">
{{item.name}}
</p>
I am getting json data from the back-end(api). And i want to display this with ngFor. I got an error message like: "Cannot find a differ supporting object '[object Object]'" from the console.
later I tried this:
#Pipe({
name: 'mapToIterable'
})
export class MapToIterable implements PipeTransform{
transform(map: {}, args: any[] = null): any {
if (!map)
return null;
return Object.keys(map)
.map((key) => ({ 'key': key, 'value': map[key] }));
}
}
and then in my view:
<li *ngFor="let detail of getEventDetails | mapToIterable">
Creator Email: {{detail.creator.email}}
</li>
this time i didn't get an error but there is no display values of {{detail.creator.email}}
Data from back-end
{
"banner_image": null,
"categories": [],
"creator": {
"email": "email#email.com",
"first_name": "Prince",
"gender": true,
"id": 15,
"last_name": "Odame",
"subscribed_categories": [],
"watchlist": []
},
"creator_id": 15,
"description": "Learn how to install solar panels in 3 days and make real money all your lifetime",
"faqs": [],
"id": 6,
"is_verified": true,
"max_tickets_per_user": 1,
"shows": [
{
"address": "Engineering Auditorium, College of Engineering, KNUST, Kumasi",
"city": "Kumasi",
"country": "Ghana",
"end_time": "2016-08-03T14:30:00+00:00",
"event_id": 6,
"id": 5,
"is_online": false,
"start_time": "2016-08-01T08:30:00+00:00",
"state": "Ashanti",
"ticket_types": [],
"venue": "Engineering Auditorium"
}
],
"tags": [],
"title": "Solar Panels Installation Workshop"
}
Thanks in advance
You probably just want to do this:
<li>Creator Email: {{getEventDetails.creator.email}}</li>
And for the arrays:
<li *ngFor="let show of getEventDetails?.shows">
Show ID: {{show.id}}
</li>
When the controller is initially loaded with data, I want the rows to appear in the same order they were added to my JSON.
When I do this in IE and FF, the rows intially appear in the order they were added, but when I do it in Chrome, the middle item (in this case row #150) appears at the beginning of the list. Why is this?
I have Json response,
[
{
"code": "4001",
"description": "Transactions",
"labelName": null,
"target": null,
"sortOrder": 100,
"iconTarget": "fa-inr"
},
{
"code": "4053",
"description": "Cash Management",
"labelName": null,
"target": null,
"sortOrder": 150,
"iconTarget": "fa-money"
},
{
"code": "4053",
"description": "Cash Management",
"labelName": null,
"target": null,
"sortOrder": 500,
"iconTarget": "fa-money"
}
]
template
<ul class="panel sidebar-nav" ng-repeat="item in model | orderBy: -item.sortOrder">
<li>child links data</li>
<li>child links data</li>
<ul>
You're close, just missing single quotes around your expression. Also, you don't need to refer to the ng-repeat name "item", only its attribute. Your code should read something like
<ul ng-repeat="item in model | orderBy: 'sortOrder'">
See this plunker.
change the angularjs version 1.5.x. It works for me.