Angular - How to display data from an array of an array? [duplicate] - javascript

This question already has answers here:
How to iterate object keys using *ngFor?
(5 answers)
Closed 4 years ago.
How would I display data from an array of arrays within Angular using *ngFor?
app.component.ts
list = {
"one": [
{
"name": "a",
"active": false
},
{
"name": "b",
"active": false
}
],
"two": [
{
"name": "c",
"active": false
},
{
"name": "d",
"active": false
}
]
};
app.component.html
<div *ngFor="let item of list">
<div *ngFor="let data of item">
{{data.name}}
</div>
<div>
The nesting of *ngFors doesn't appear to work in this case, but I cannot figure out why.
stackblitz

use keyvalue pipe
Stackblitz Demo
<div *ngFor="let item of list | keyvalue">
<div *ngFor="let data of item.value">
{{data.name}}
</div>
<div>
if you are using angular 5 and 6
<div *ngFor="let item of getListData">
<div *ngFor="let data of list[item]">
{{data.name}}
</div>
</div>
get getListData(){
return Object.keys(this.list)
}

Your outer "list" is no list at all. It is an object.
Since objects are not strictly ordered by spec, they are not iteratable by Angular's ngFor.
However, with Angular 6.1 a new pipe was introduced, which actually makes objects iteratable as well, namely the KeyValue pipe.
So if you are using Angular 6.1 you may use that. Otherwise you will have to implement such a pipe on your own or prepare your data in your controller accordingly.
http://www.talkingdotnet.com/angular-6-1-introduces-new-keyvalue-pipe/

Related

How to access first or second object in JSON

I want to access the first object in my json, but the name changes for each product. For example: one product has product.custom.6244816 and another one product.custom.4298205
This is what I have to acces product.custom
{{ product.custom | json_encode(constant('JSON_PRETTY_PRINT')) }}
This is product.custom
{
"6244816": {
"id": "6244816",
"type": "select",
"required": true,
"max_chars": false,
"title": "Selecteer voorzetplaat (verplicht)",
"value": false
}
}
How can I access product.custom.6244816 (in this case) without typing the specific numbers behind product.custom?
If you need more information, feel free to ask.
Thanks in advance!
I think you can access it this way:
product.custom[0]
You can use Object.keys (which will give you array of keys in order) and then use the first key to access the value on that
var result = {
"6244816": {
"id": "6244816",
"type": "select",
"required": true,
"max_chars": false,
"title": "Selecteer voorzetplaat (verplicht)",
"value": false
}
}
console.log(result[Object.keys(result)[0]]);
result will product.custom in your example
If you want to do this in twig, there are two easy solutions
Use the filter first
The filter will return the first item of an array
Use the filter keys
The filter will return an (zero-based) indexed array of the keys of the array you've passed. This way u can defined which item u want to return from an associative array
{% set foo = {"6000":{"name":"foo"},"7000":{"name":"bar"},"8000":{"name":"foobar"}} %}
{{ (foo|first).name }} {# out: foo #}
{{ foo[(foo|keys)[1]].name }} {# out: bar #}
demo

Blank screen in vue.js if not using created() life cycle hook or spread operator (...)

The following example gives me a blank screen (jsfiddle here). Even the parts which have nothing to do with the loop are not being rendered.
HTML:
<div id="app">
<button #click="objectFromApi">
run objectFromApi function
</button>
<div
v-for="obj in myObject[0].results"
:key="obj.id"
>
<p>
{{ obj.message }}
</p>
</div>
</div>
JavaScript:
new Vue({
el: "#app",
data: {
myObject: []
},
methods: {
objectFromApi: function(){
this.myObject.push(
{
"count": 5,
"results": [
{
"id": 1,
"message": "object 1"
},
{
"id": 2,
"message": "object 2"
}
]
}
)
}
},
//created() {
// this.objectFromApi()
//}
})
Nevertheless it does work if:
1.) Either using objectFromApi function directly in the created life cycle hook (what I don't want!)
created() {
this.objectFromApi()
}
2.) Or (without the use of created life cycle hook) if I go directly into the nested results array and spread the objects out like this (what I also don't want!)
this.myObject.push(
...{
"count": 5,
"next": "http://127.0.0.1:8000/api/someurl/?page=2",
"previous": null,
"results": [
{
"id": 1,
"message": "object 1"
},
{
"id": 2,
"message": "object 2"
}
]
}.results
)
When using option 2.) of course the v-for loop has to look different:
v-for="obj in myObject" instead of v-for="obj in myObject[0].results"
What is wrong with my initial example?
When the component is first rendering the array myObject will be empty.
During rendering it attempts this:
<div
v-for="obj in myObject[0].results"
:key="obj.id"
>
The value of myObject[0] will be undefined. Attempting to access the results property of undefined will result in an error. This error will cause rendering to fail. Nothing will be shown, even the parts that didn't fail.
There are various ways to fix this problem. You could prepopulate the data with suitable empty properties:
data: {
myObject: [
{
results: []
}
]
}
Alternatively, as you've noted, you could change the loop to use v-for="obj in myObject", changing objectFromApi accordingly to only store the results array in myObject. Even if you don't want that exact change some similar change is probably a good idea because the [0] part strongly suggests you've got a problem with your data model. The key thing here is that it avoids trying to access nested objects that don't exist. The use of the spread operator in your second example is largely irrelevant.
Or you could skip the loop in the template:
<template v-if="myObject[0]">
<div
v-for="obj in myObject[0].results"
:key="obj.id"
>
...
</div>
</template>

ng-repeat not showing array generated from objects received from the web service response in Ionic

I am developing an ionic v1 app where it gets a response from the server in json format and puts the data inside an array.
I'm trying to display this array elements inside an HTML div as a checkbox list that user can select the items by checking the checkbox. My problem is that array is not being displayed in the HTML page can anyone please help me on this?
This is my HTML Code
<div id="btnid" class="list itemsDiv">
<ion-list class="bg" ng-repeat="item in results">
<ion-checkbox ng-repeat="item in results">
{{ item.ItemName }}
</ion-checkbox>
</ion-list>
</div>
And here is my Angular Code:
$http({
url: 'http://Website/Webform?id=1',
method: "GET"
})
.then(function(response) {
$scope.temp = response.data;
$scope.results = response.data.Cargo;
console.log($scope.results);
$scope.result = [];
$scope.listPref = [];
$scope.checkItems = {}
for (var j = 0; j < $scope.temp.Cargo.length; j++) {
var result1 = $filter('filter')($scope.temp.Cargo, {
CategoryTypeID: 1
})[j];
$scope.name = result1.ItemName;
$scope.listPref.push($scope.name);
}
console.log($scope.listPref);
}
and here is the json Data which i 'm getting:
{
"Cargo": [{
"ID": 1,
"ItemName": "test",
"CategoryTypeID": 1
}, {
"ID": 2,
"ItemName": "test2",
"CategoryTypeID": 1
}, {
"ID": 3,
"ItemName": "test3",
"CategoryTypeID": 1
}]
}
here is the image of my console window which shows me the object and array elements
You could also try to force angular to update the UI using $scope.$apply function, this is caused by the using of promises and callbacks, check this article to a better comprehension.
Article about Apply
Try this..
Actually, you forgot ng-model there and the second problem is you used ng-repeat twice on your code. But there is no necessity of that.
<div id="btnid" class="list itemsDiv">
<ion-list class="bg" ng-repeat="item in results">
<ion-checkbox ng-model="item.ItemName">
{{item.ItemName}}
</ion-checkbox>
</ion-list>
</div>

How to display nested JSON objects using ng-repeat with Ionic framework?

I am developing a simple hybrid mobile app using the Ionic framework. When you search for a last name, a GET request is sent to retrieve all matching last names, and then displays their corresponding ID's. I am having an issue displaying the returned data from the JSON object.
Below is the html page:
<ion-view view-title="Account" ng-controller="AccountCtrl">
<ion-content>
<div class="list">
<div class="item item-input-inset">
<label class="item-input-wrapper">
<input type="text" placeholder="Search" ng-model="name">
</label>
<button class="button button-small" ng-click="searchUser(name)">
Go
</button>
</div>
</div>
<div>
<ul ng-repeat="user in $results">
<li>{{user.id}}</li>
</ul>
</div>
</ion-content>
Next is the js file that successfully returns a populated JSON object with everything I need.
angular.module('starter.controllers', [])
.controller('AccountCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.searchUser = function (name) {
$http.get('https://notrelevantforthis/searchLastName?=' + name).then(function (response) {
console.log(response.data)
//Assign JSON obj to results to repeat through and display data
$scope.results = response.data;
//To show the actual JSON object is returned
//var jsonStr = JSON.stringify($scope.results);
//document.body.innerHTML = jsonStr;
}, function (error) {
console.log(error)
});
};
}]);
Now the important part is the structure of the JSON object itself. I think this is where I am getting confused. The structure is like the following:
{
"response": {
"totalFound": 275,
"start": 0,
"acc": [
{
"id": [
"1"
],
"first_name": [
"Joe"
],
"last_name": [
"Smith"
]
},
{
"id": [
"2"
],
"first_name": [
"John"
],
"last_name": [
"Doe"
]
}]}
}
My problem is iterating through the JSON object using ng-repeat I think. For some reason none of the data is being displayed, but the object is definitely there when looking at the console. Any help or direction in what I am doing wrong would be much appreciated, as I am new to this and have been trying to find the correct way to do this.
EDIT:
Tried using collection-repeat as well offered by the ionic framework but was getting stack limit errors.
When you're assigning response.data to $scope.results, you're literally assigning the HTTP's response body to it, which is the whole JSON object that you have in your question. You would need to actually point to response.data.response.acc if you wanted to ng-repeat through those accounts.
In your template, it should just be ng-repeat="user in results", without the $ in front of results.
Your JSON object lists the id for each account as an array, I'd recommend just giving the literal value without the array, otherwise in your ng-repeat you'll have to use {{user.id[0]}} to actual print the value without printing the array itself.
I've created an example for you here: http://plnkr.co/edit/GYeF4FzVHl8Og5QTFcDx?p=preview

Display an Array inside Object using ng-repeat -AngularJs

Below is my JSON object which I would like to display the name in both the parent and child array.
$scope.result= [
{
"id": 1,
"name": "1002",
"parentArray": [
{
"id": 28,
"name": "PRODP1",
"shortCode": "PRODP1"
}
]
}
I want to display Name:1002 Parent_Name:PRODP1
I tried {{item.name}} which will only display 1002.But I need to display the name of parentArray as well.
Since the parentArray is also an array your going to need a nested ng-repeat.
If this is a large page then this may cause a performance issue.
<div ng-repeat="item in result">
{{item.name}}
<div ng-repeat="innerItem in item.parentArray">
{{innerItem.name}}
</div>
</div>
parentArray is an...array, so you need to access it using an index:
<div ng-repeat="item in result">
Name: {{ item.name }} Parent_Name: {{ item.parentArray.length ? item.parentArray[0].name : '' }}
</div>
That's under the assumption that there is one object in parentArray. You might need to iterate it, or you might need to check to see if it exists depending on your requirements.

Categories

Resources