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
Related
From the contacts, I'd like to select the values in fields: "Id" (47) and everything from the nested array [doNotContact]. I could use some help defining the JSONPath-filter I should be using to select the values: 47 and each value inside the nested array.
{
"total": "1",
"contacts": {
"47": {
"id": 47,
"isPublished": true,
"dateAdded": "2015-07-21T12:27:12-05:00",
"createdBy": 1,
"createdByUser": "Joe Smith",
"doNotContact": [{
"id": 2,
"reason": 2,
"comments": "",
"channel": "email",
"channelId": null
}]
}
}
}
I have tried paths like: $.contacts.*.['id','doNotContact'] however, this does not seem to work. I am using the website: https://goessner.net/articles/JsonPath/ normally this would help me solve the problem.
Not all implementations support the comma-delimited selectors, e.g. ['id','doNotContact']. See the JSON Path comparison project site (specifically this test) for information as to which implementations support the syntax.
Secondly, please see this answer about omitting the dot before a bracket syntax
This is my json response data. I would like to display this data in listview using map but i dont know how to convert the objects of objects to array of data.
{
"success": true,
"data": {
"addresses": {
"abc": {
"address_id": "121",
"firstname": "Demo",
"lastname": "User",
"company": "Demo Company name",
"telephone": "1-541-754-3011",
"address_1": "Demo",
"address_2": "test address",
"postcode": "3333",
"city": "Berlin",
"zone_id": "1256",
"zone": "Berlin",
"zone_code": "BER",
"country_id": "81",
"country": "Germany",
"longitude": "",
"lattitude": "",
"iso_code_2": "DE",
"iso_code_3": "DEU",
"address_format": "{company}\r\n{firstname} {lastname}\r\n{address_1}\r\n{address_2}\r\n{postcode} {city}\r\n{country}",
"custom_field": null
}
}
}
}
I assume you want to display dynamic keys (eg: abc) inside addresses object. For this, you need to iterate through addresses object for keys and values.
//json you provide
addresses = json["data"]["addresses"];
addresses.forEach((final String key, final value) {
//here key will be abc & value will be json object
//you can add key or value to a different list and use for list rendering later
});
You can use JSON to dart tool, which is available online for free.
Paste your JSON to left panel and select dart language from upper right corner,
You will get your dart class code, in which you can use methods like .toMap() and .toJson(),
This can be very helpful for huge JSON data.
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/
I'm using angular-schema-form in my project and trying to add an empty array in my model.
I expected that array type schema form will not contain any items but it actually pushed one object in my array and showed it in from.
How can I init form with no items in array?
html
<div ng-app="app" ng-controller="Controller as ctr">
<form sf-schema="ctr.schema" sf-form="ctr.form" sf-model="ctr.model"></form>
{{ctr.model.comments}} - Where this object come from? This array was empty. Is it possible to keep it empty on load?
</div>
js
var myApp = angular.module('app', ['schemaForm'])
.controller("Controller", function() {
this.schema = {
"type": "object",
"title": "Comment",
"properties": {
"comments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"comment": {
"title": "Comment",
"type": "string",
"maxLength": 20,
"validationMessage": "Don't be greedy!"
}
}
}
}
}
};
this.form = [{
"key": "comments",
"items": [
"comments[]"
]
}];
this.model = {
comments: [] // Empty array defined
};
});
Jsfiddle
The value you are looking for is startEmpty: true this will avoid pre-populating the array with an object.
Angular Schema Form: Array Documentation
The pre-population is defaulted to ensure that the form fields within an array are available when the form loads. The startEmpty: true value can override this behaviour.
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>