Angularjs iterate through multiple json arrays - json

I'm quite new to Angularjs, and I'm doing an $http.get from a json. I've gotten the response and it works. The only problem is that I have to hard-code the handlebars rather than do a ng-repeat
{{country.results[0]["breakfast/_text"][1] }}
{{country.results[0]["breakfast/_text"][2] }}
{{country.results[0]["breakfast/_text"][3] }}
{{country.results[1]["breakfast/_text"][1] }}
{{country.results[1]["breakfast/_text"][2] }}
{country.results[1]["breakfast/_text"][3] }}
{{country.results[1]["breakfast/_text"][4] }}
{{country.results[2]["breakfast/_text"][1] }}
{country.results[2]["breakfast/_text"][2] }}
{{country.results[2]["breakfast/_text"][3] }}
{{country.results[3]["breakfast/_text"][1] }}
{{country.results[3]["breakfast/_text"][2] }}
How do I do an ng-repeat for a 2-d json array like this?

You should use two nested ngRepeat directives. This should render it:
<div ng-repeat="result in country.results">
<div ng-repeat="(key, value) in result['breakfast/_text']">
{{value}}
</div>
</div>

I have created a plunker and use ng-repeat for 2D data like this.
$scope.data = [
{'text':[1,2,3]},
{'text':[3,4,5]},
{'text':[5,6,7]},
];
and
<div ng-repeat="result in data">
<div ng-repeat="value in result">
<div ng-repeat="values in value">
{{values}}
</div>
</div>
</div>
This might help you .

Related

Change dynamically style in Angular with ngfor array data

I want to set the width as dynamically with the data that i am gonna take from the array. But angular doesn't let me set it with usual way. How can i handle it ?
<div *ngFor="let item of products">
<div [style.width.px]="{{ item.size }}" class="Holiday"></div>
</div>
you do not need {{ }} when you're using [].
change [style.width.px]="{{ item.size }}" to [style.width.px]="item.size" and it should work.
Use ngStyle to apply dynamic styles.
<div *ngFor="let item of products">
<div [ngStyle]="{ 'width' : item.size+'px' }" class="Holiday"></div>
</div>
Demo : https://stackblitz.com/edit/angular-fel5sk

Symfony twig div

I made a form with the FormBuilder of Symfony.
When I put my form in twig, the form_start(form) and form_end(form), it add a tag for each input.
I don't understand why twig adds a tag.
What is the solution to remove this tag
Thanks for your answer :)
Also, my formbuilder is like that :
->add('title', TextType::class, array(
'label'=>false,
'attr'=>array('autofocus'=>true)
))
my twig is like that :
{{ form_start(form) }}
<div class="row">
<div class="col-sm-9 p-1">
{{ form_row(form_record.title, {'attr':{'class':"form-control", 'placeholder':"Description"|trans, 'title':"Description"|trans }}) }}
{{ form_errors(form_record.title) }}
</div>
<div class="col-sm-1 pt-2">
<button type="submit" class="btn btn-success btn-circle btn-sm">
<i class="fas fa-plus"></i>
</button>
</div>
</div>
{{ form_end(form) }}
and the result in the html source code is :
<div class="row">
<div class="col-sm-9 p-1">
<div>
<input type="text" id="app__title" name="app_[title]" required="required" class="form-control" placeholder="Description" title="Description">
</div>
</div>
</div>
So Twig add the
<div>
that I don't want. How can I remove this autocompleted tag?
I tried the
{% do form_record.title.set rendered %}
but maybe I think that it does not work.
Edit: Okay it seems I misunderstood the issue at first.
I thought you wanted to hide a field you had in your form which can be done with
{% do form.myField.setRendered %}
Now that I understand the issue, I believe it comes from the way your field is being printed.
There are 3 main components to a form field.
Label: form_label(form.field)
Widget: form_widget(form.field)
Errors: form_errors(form.field)
There is a way to print all three components at once. The function is
form_row(form.field)
Here comes the culprit: form_row(). Because it normally prints 3 different components, it adds a div around it!
Futhermore, by looking at the form type and seing 'label' => false, I can say that the label was printing at first using form_row.
To avoid having to define 'label'=>false everytime, you can simply print your form field in this manner:
{{ form_widget(form_record.title, {'attr':{'class':"form-control", 'placeholder':"Description"|trans, 'title':"Description"|trans }}) }}
{{ form_errors(form_record.title) }}
You can simply omit {{form_label(form_record.title)}} and it won't print.
On the other hand, I also noticed something that might be okay but seem wrong with the given example.
In the twig you shared, the form starts with {{ form_start(form) }} but then the field is {{ form_row(form_record.title)}}.
From where I come from form_record is undefined here. I would use {{ form_row(form.title)}}
Anyways, the explanation for the difference between form_row and form_widget can be found here: Symfony form differences between row and widget
Enjoy!

*ngfor split data of an array

I consume a external JSON API with this array.
temperature_mean: [ 16.94,19.9,19.13,15.22,15.52,15.62,12.47 ],
I want to split this array into seperated objects with an *ngFor loop:
<div class="card">
<h2>Temperature</h2>
<div *ngFor="let temp of cityTemperature">
{{cityTemperature}}
</div>
</div>
That's what I got back:
But I want on each line only one object. How can I do that and seperate this loop?
You need to change your html to:
<div class="card">
<h2>Temperature</h2>
<div *ngFor="let temp of cityTemperature">
{{ temp }}
</div>
</div>

Iterate through an array in angularjs

i want to iterate through array elements and print them one by one.
currently i have this HTML code.
<div data-ng-repeat="i in range">
<div ng-repeat="rhit in hits[i]">
<p > {{ rhit }}</p>
</div>
</div>
here
"range" is an array with values till 100([0,1,2,....,100])
"hits" is an array containing more than one element
if i try separately printing like this, it works
<p > {{ hit[0] }}</p>
<p > {{ hit[1] }}</p>
<p > {{ hit[2] }}</p>
i also tried this code but it doesn't print anything.
<div ng-repeat="rhit in hits">
<p > {{ rhit }}</p>
</div>
this is my actual query result
"aggregations": { "by_id": { "doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0, "buckets": [ {
{"key":"60","doc_count":21,
"tops":{
"hits":{
"total":21,"max_score":2.2237754,
"hits":[{"_index":"automatch_testing","_type":"temp_135","_id":"AVU7i0nnXK6g_oqHu-az","_score":2.2237754,"_source":{"t_pacs_id":"34","t_id":"60","matching":"MO"}},
{"_index":"automatch_testing","_type":"temp_143","_id":"AVU7iOSeXK6g_oqHu-XY","_score":2.2237754,"_source":{"t_pacs_id":"30","t_id":"60","matching":"MO","t_match":"matched"}},
{"_index":"automatch_testing","_type":"temp_135","_id":"AVU7i0nlXK6g_oqHu-ay","_score":2.2237754,"_source":{"t_pacs_id":"28","t_id":"60","matching":"MO","UICriteria":"135","t_match":"matched"}}]}}}
here i want to print the field "t_pacs_id" of each document in hits...
is there any way the above code can be run?? please suggest.
many thanks.
here is the plunker
If you are interested to get the hits collection ith place then you could directly do hits[i] instead of having another ng-repeat
<div data-ng-repeat="i in range">
<p> {{ hits[i] }}</p>
</div>
You say that separately printing something like this works:
<p > {{ hit[0] }}</p>
In that code, you are accessing an array named "hit", but in your code that does not work, you are using ng-repeat to iterate over an array named "hits". What do you get when you try:
<div ng-repeat="rhit in hit[i]">

Limitations on polymer conditional templates?

I'm working on a set of conditional views based on the data available in a JSON object - effectively, show a media view if we have media to show, show a document view if we have merely text information to show, etc. The approach I've been using to date uses hasOwnProperty() to check the JSON object to determine the available data and work out the view template based on what's there.
I've implemented something as a barebones version of this, but now I get nothing at all. The if seems to just kill the nested templates. Here's what I'm trying:
<template bind if="{{ posts[postid].hasOwnProperty('video') }}">
<div class="tileHeader">Posted by #{{ posts[postid].creator_id }} <time-ago datetime="{{ posts[postid].creation_date }}"></time-ago></div>
<div class="tile">
<div class="heroTop" style="background-image: url({{ posts[postid].body }}) no-repeat"></div>
<div class="heroBottom">
<div class="headline">{{ posts[postid].url_title }}</div>
<div class="postDesc">{{ posts[postid].url_description }}</div>
</div>
<div class="attribution">
{{ posts[postid].url }}
</div>
</div>
</template>
<template bind if="{{ posts[postid].hasOwnProperty('image') }}">
<div class="tileHeader">Posted by #{{ posts[postid].creator_id }} <time-ago datetime="{{ posts[postid].creation_date }}"></time-ago></div>
<div class="tile solo-view">
<div class="heroSolo">
{{ posts[postid].body }}
</div>
<div class="attribution">
{{ posts[postid].url }}
</div>
</div>
</template>
Two questions:
1. Can this if statement work in this context, or does this need to be re-built as a filter?
2. What happens in the case where both ifs are true for a given render?
Ok, this seems to be working. Is it messy? Yes, definitely.
Effectively, from my API I get a slew of post_ids that I need to format differently depending on what I'm finding. Trying to use something like JSON.hasOwnProperty didn't work (don't know why) so I'm resorting to assigning a variable based on a separate discovery function.
Is there a better way to do this? Of this, I'm certain. If you've got a better approach, please do let me know. But here's what I've come to:
<template repeat="{{ postid in postids }}">
<core-ajax id="postdetail" url="api/1/posts/{{ postid }}" data-postid="{{ postid }}" postid="{{ postid }}" handleAs="json" method="GET" auto on-core-response="{{ updatePostDetail }}"></core-ajax>
<template if="{{ posts[postid].displaytype == 'articleImage' }}">
<div class="tileHeader"><user-print creatorid="{{ posts[postid].creator_id }}" prepend="Posted by" size="small"></user-print> <span hidden?="{{ showchannel }}">In channel {{ posts[postid].channel_id }}</span> <time-ago prepend="Last update " isostring="{{ posts[postid].creation_date }}"></time-ago></div>
<div class="tile media-view" style="background: url({{ posts[postid].banner }}) no-repeat; background-size: cover;" title="{{ posts[postid] | descText }}">
<div class="heroBottom">
<div class="type">{{ posts[postid].displaytype }}</div>
<div class="headline">{{ posts[postid].url_title }}</div>
<div class="postDesc">{{ posts[postid].body | stripTags | shorten }}</div>
<div class="attribution"> {{ posts[postid].url }} </div>
</div>
</div>
</template>
<template if="{{ posts[postid].displaytype == 'video' }}">
... (etc)
</template>
</template>
<script>
Polymer('post-list', {
postids: [],
posts: {},
created: function(){
},
ready: function(){
},
updatePostList: function(e){
this.postids = e.detail.response.post_ids;
},
updatePostDetail: function(e){
json = e.detail.response.post;
postid = json.id;
this.posts[postid] = json;
this.posts[postid].displaytype = 'barePost'; // default value so I don't have to worry about a bunch of similar 'else' statements
this.posts[postid].hasVideo = 'noVideo'; // ditto
if(json.hasOwnProperty('url_meta_tags')){
if(json.url_meta_tags.hasOwnProperty('og:video') || json.url_meta_tags.hasOwnProperty('twitter:player:stream')){
this.posts[postid].hasVideo = 'video';
this.posts[postid].displaytype = 'video';
}
else if(json.url_meta_tags.hasOwnProperty('og:image') || json.url_meta_tags.hasOwnProperty('image') || json.hasOwnProperty('banner')){
if(json.body.length > 350){
this.posts[postid].displaytype = 'longArticle';
}
else if(json.body.length > 0){
this.posts[postid].displaytype = 'articleImage';
}
else{
this.posts[postid].displaytype = 'bareImage';
}
}
}
else if(json.hasOwnProperty('files')){
this.posts[postid].displaytype = 'embeddedMedia';
}
}
</script>
From the documentation: https://www.polymer-project.org/docs/polymer/binding-types.html#importing-templates-by-reference
You could use the ref attribute combined with bind to make this less of a mess.
<!-- Create Your displayType templates -->
<template id="longArticle">
<!-- template for displayType === longArticle -->
</template>
<template id="bareImage">
<!-- template for displayType === bareImage -->
</template>
<!-- then construct your loop -->
<template for={{postid in postids}}>
<template bind ref="{{posts[postid].displaytype}}"></template>
</template>