Display an Array inside Object using ng-repeat -AngularJs - javascript

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.

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

Looping through Object containing two different arrays in VueJS

I'm currently working on a chat program written in VueJS and have a problem when trying to display the message with a given timestamp, because I need to loop inside an object containing two arrays (message array and timestamp array)
My data object looks like this:
messages: [ //saving text-messages of each chatroom in order (0 => chatroom1, 1 => chatroom2, ..)
{ //chatroom1 with static data for testing
text: ["first message chatroom1", "second message chatroom1"],
time: ["08:38", "09:02"]
},
{ //chatroom2
text: [],
time: []
},
{ //chatroom3
text: [],
time: []
}
]
When I would try to loop only through the text[] Array, my code would look like this:
<p class="message-class message-send" v-for="messages in messages[values.num].text">{{ messages }}</p>
giving me back
<p class="message-class message-send">first message chatroom1</p> //messages[0].text[0]
<p class="message-class message-send">second message chatroom2</p> //messages[0].text[1]
The [values.num] is the number of the selected chatroom passed in order to select the specific data (0 for chatroom1, ...)
When trying to iterate through text and time in one single loop (surely I want the time to be displayed beyond every single text message and not after all messages) I thought something similar to this should do the work:
<div v-for="messages in messages[values.num]">
<p class="message-class message-send">{{ messages.text }}</p>
<span class="message-time-send">{{ messages.time }}</span>
</div>
The problem in this case is that I display the whole text and time array without iterating through the arrays itself.
Trying something like
<p class="message-class message-send">{{ messages.text[some number] }}</p>
also doesn't work.
Is there anyone who can help me solving this problem? Or should I consider trying to build the messages object in a different way
This should work.
<div v-for="(message, index) in messages[values.num].text">
<p class="message-class message-send">{{ message}}</p>
<span class="message-time-send">{{ messages[values.num].time[index] }}</span>
</div>
Generally, a structure like this would be preferrable:
messages: [
[ // room 1
{
"time": "08:38",
"text": "first message chatroom1"
},
{
"time": "09:02",
"text": "second message chatroom1"
}
],
...
]
Because logically, timestamp and message text are both properties of one single "chatroom message" item. But if you can't or do not want to change your structure, you can get the index in a v-for statement like this: v-for="(message, index) in messages[values.num].text" (see the official docs). Then you can use that same index to access the corresponding item in the time array:
<div v-for="(message, index) in messages[values.num].text">
<p class="message-class message-send">{{ message}}</p>
<span class="message-time-send">{{ messages[values.num].time[index] }}</span>
</div>

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

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/

Meteor - How to use {{each}} to display multiple arrays from mongoDB in a table?

I have a collection named "pIds" in mongoDB and with multiple arrays:
{
"_id" : "Coms>f41a3480af751a7a",
"pIds" : [
"pid_833d82c2f32b7dc0",
"pid_833d82c2f32b7dc0",
"pid_833d82c2f32b7dc0",
],
"dudes" : [
"AB",
"AC",
"BC"
],
"ho" : [
"Coms>f41a3480af751a7a",
"Coms>f41a3480af751a7a",
"Coms>f41a3480af751a7a"
],
"ps" : [
"vf",
"ou",
"rwf"
],
}
Now I want to render these elements dynamic into a HTML table so that the table changes the same way the data in the collection changes. So the table should automatically add new elements, when new elements are written into the collection "pIds". I thought about using {{each}}.
JS-Helper:
Template.home.helpers({
'pIdsRendering': function() {
if (Meteor.userId()) {
var pId = pIds.find({'_id': Session.get('pIdshome')}).fetch();
return pId;
}
},
});
HTML:
<tbody>
{{#each pIdsRendering}}
{{#each pIds}}
<tr><td>{{this}}</td></tr>
{{/each}}
{{/each}}
{{#each pIdsRendering}}
{{#each dudes}}
<tr><td>{{this}}</td></tr>
{{/each}}
{{/each}}
[...and so on...]
</tbody>
Actually this works and new elements are added to the table, but I just canĀ“t put the content into the right cells of the table. It puts the content all in one column like the data of the table would be written like this:
So, I think it is about "logical order", but I just can not get it done...In the end the table should look like this:
You create for every array item new <tr> tag and this is the reason why every item is in a new row. I suggest you to change your collection schema a little bit. I would do it like below:
{
"_id" : "Coms>f41a3480af751a7a",
"data": [
{
"pid": "pid_833d82c2f32b7dc0",
"dude": "AB",
"ho": "Coms>f41a3480af751a7a",
"ps": "vf"
},
{
"pid": "pid_833d82c2f32b7dc0",
"dude": "AC",
"ho": "Coms>f41a3480af751a7a",
"ps": "ou"
}
]
}
Then in your Blaze template you can show records much easier
{{ #each record }}
{{ #each data }}
<tr>
<td>{{ pid }}</td>
<td>{{ dude }}</td>
<td>{{ ho }}</td>
<td>{{ ps }}</td>
</tr>
{{ /each }}
{{ /each }}
Your actual schema can lead to unexpected errors. For example when pIds array will have more elements than dudes. It is more difficult to validate it. By using an object you can do it much more easily. Also, I guess that you want to bind pIds[index] element with dudes[index] element. In this case using arrays like you did isn't a correct way.

Angularjs variable value is not updating

I am using angular with bootstrap modal,i have a json stored in a scope variable products in a controller as follow
controllers.productController = function($scope) {
$scope.products = {"meta": {"total_count": 3}, "objects": [{ "id": 3, "image": "/media/products/1/Product007_image.JPEG", "image2": "/media/products/1/Product007_image2.JPEG",}, {"id": 4, "image": "/media/products/1/Product009_image.JPEG", "image2": "/media/products/1/Product009_image2.JPEG"},{"id": 13, "image": null, "image2": null}]}
$scope.fetchModal = function(index) {
$scope.activeProd = index;
$('#product_desc').modal();
}
}
index.html
<div ng-controller="productController">
<div class="product-list">
<span ng-repeat="product in products.objects" ng-click="fetchModal(index)" >{{ product.id }}</span>
</div>
<div id="product_desc">
<img ng-src="{{products.objects[activeProd].image }}" />
{{ products.objects[activeProd].id }}
</div>
</div>
it works all fine, the problem is that if i click on a product in product-list which has image it renders modal with image and then click on a product which have image value null i.e no image, in its model the previous product image still exist instead i should get nothing. I hope i am clear to my point
i observed that the ng-src is changing and assigning to null but the src attribute is not changing
I think your problem is that when you change the ng-src to null the older value is retained in the image source.
This is the proper angular behavior. You can find the details on this thread :
https://stackoverflow.com/a/22094392/1649235
If you go through this thread you will also find a workaround i.e. don't put your image path as null where it is supposed to be empty, put it equal to '//:0'.

Categories

Resources