Why is my ng-repeat is only displaying first result? - angularjs

I have this array of an array of objects that I am pushing onto from results I pass from a modal;
[
[
{
"id": 4,
"name": "THROTTLE TUBE",
"partno": "104-",
"oemnumber": "46019 038",
"stock": 19,
"price": "28"
},
{
"id": 28,
"name": "TACHOMETER, CUP",
"partno": "128-",
"oemnumber": "25012 011",
"stock": 7,
"price": "46"
}
]
]
I am getting this from the following;
$scope.woParts = [];
//later in my modal code - which is where the double [] is coming from
modalInstance.result.then(function(woParts) {
$scope.woParts.push(woParts);
I am then using this ng-repeat in my view;
<div ng-repeat="woPart in woParts">
<div class="col-md-4">
#{{ woPart[$index].name }}
</div>
<div class="col-md-2">
#{{ woPart[$index].oemnumber }}
</div>
<div class="col-md-2">
#{{ woPart[$index].price | currency}}
</div>
<div class="col-md-2">
<input type="number"
class="form-control"
ng-model="partQty">
</div>
</div>
This only displays the first result in the array. Why is that?
Thanks!

I don't think you should push woParts into another object. Just save it to the scope: $scope.woParts = woParts;. Then there is no need to use $index in the ngRepeat, just use regular dot notation: woPart.name.
Or if you have to push woParts into another array, then you can change the ngRepeat expression to woPart in woParts[0].

Related

Iterate following Json using ng-repeat

I am trying to iterate following json inside ng-repeat but not working. I would like to get both Ques and img. Below, I have tried "Ques" part but it doesn't display anything.
[{
"Ques": [{
"column1": "3",
"column2": "ok?"
}, {
"column1": "4",
"column2": "test"
}],
"img": [{
"column1": "21",
"column2": "CDH.PNG"
}, {
"column1": "22",
"column2": "Feedback.PNG"
}]
}]
My code given below
var messages = JSON.stringify(response.data);
$scope.messages = JSON.parse(messages);
<div class="list-group-item" ng-repeat="item in messages.Ques">
<h4 class="list-group-item-heading">{{item.column2}}</h4>
<p class="list-group-item-text">{{item.column1}}</p>
</div>
I have done this way. Its working. I can also use "Img" same like below.
<div class="list-group-item" ng-repeat="item in messages">
<div ng-repeat="items in item['Ques']">
<h4 class="list-group-item-heading">{{items.column2}}</h4>
<p class="list-group-item-text">{{items.column1}}</p>
</div>
</div>

check with *ngIf, if there is an array or not (Angular 4)

I'm looping through a json file with *ngFor. While looping through the data, I want to check for every person, if it has no colors array. I do this with *ngIf.
JSON
[
{
"name": "Peter",
"colors": [
{
"color": "blue"
},
{
"color": "yellow"
}
]
},
{
"name": "Maria"
}
// has no colors array
]
HTML
<div *ngFor="let person of persons">
<div *ngIf=" what comes here?? ">
<p>{{person.name}} has no colors</p>
</div>
</div>
How can I check, if a person has no colors array?
Try this
<div *ngFor="let person of persons">
<div *ngIf="person.colors && person.colors.length">
With words, it gives
If the array exists and has at least one element in it
The opposite would be
<div *ngIf="!person.colors || !person.colors.length">
Which you can shorten with an Elvis operator
<div *ngIf="!person.colors?.length">
Very simply :
<div *ngIf="!person.colors">
<p>{{person.name}} has no colors</p>
</div>

Cant display data from array in AngularJS

I have a problem with the print out Data from the array.
I have
{{orders}} =
[{"item":"DELL","quantity":6,"price":144},
{"item":"Samsung","quantity":3,"price":3131},
{"item":"222222","quantity":1,"price":31},
{"item":"111111111","quantity":1,"price":13}]
I try in View
<div ng-repeat="order in orders track by $index">
<span>{{ order[$index].item }}
</span>
</div>
And nothing. Can someone help me with that??
Edit:
Still does not work
{{orders}}
<div ng-repeat="order in orders track by $index">
<span>
{{order.item}}
</span>
and nothing
controller:
$scope.ListOfOrders = function () {
return ApiService.cart.list().then(function (resp) {
$scope.orders = resp[0].order;
console.log(resp[0].order)
});
}
UI
<div ng-repeat="order in orders track by $index">
<span>{{order.item}}</span>
</div>
Controller
$scope.orders = [{
"item": "DELL",
"quantity": 6,
"price": 144
}, {
"item": "Samsung",
"quantity": 3,
"price": 3131
}, {
"item": "222222",
"quantity": 1,
"price": 31
}, {
"item": "111111111",
"quantity": 1,
"price": 13
}]
Working Solution
You don't need to bind order[$index], ng-repeat itself iterates over every object so just write :
<div ng-repeat="order in orders track by $index">
<span>{{ order.item }}
</span>
</div>

Binding to correct model - with same name

I have an ng-repeat that displays 2 forms (the array has 2 items)
I have an empty input for each of these, that has the same model, something like the following:
<div ng-repeat=“group in groups”>
<form>
<input type=“text” ng-model=“group.name” placeholder=“name” />
</form>
</div>
Now this works well, until I try to enter text into the first input, it automatically enters into the second as well.
Is there an easy way to bind to the input i’m actually typing in?
Thanks
Your PLNKR example doesn't match your question.
Simplifying your code:
<!-- Top loop doesn't repeat -->
<div ng-repeat="group in groups">
<div ng-repeat="g in group">
<div ng-repeat="info in g.info.data">
<input ng-model="info.name" placeholder="Name" />
</div>
<!-- This is the problem -->
<input ng-model="test.name" placeholder="Name">
<button ng-click="nameAdd($parent.$index)">
Add
</button>
</div>
</div>
The input with the Add button uses the same ng-model name. Also here are three nested loops when only two are needed.
The Data
$scope.groups = {
"data": [{
"id": 1,
"name": "Group 1",
"site_id": 3,
"info": {
"data": [{
"id": 1,
"name": "Jim"
}]
}
}, {
"id": 2,
"name": "Group 2",
"site_id": 3,
"info": {
"data": [{
"id": 10,
"name": "Bob"
}, {
"id": 11,
"name": "Terry"
}]
}
}]
}
Change the template to:
<!-- remove top loop
<div ng-repeat="group in groups">
-->
<div ng-repeat="groupDatum in groups.data" ng-cloak>
<div ng-repeat="infoDatum in groupDatum.info.data">
<input ng-model="infoDatum.name" placeholder="Name" />
</div>
<!-- use groupDatum to store new name -->
<input ng-model="groupDatum.newName" placeholder="Name">
<!-- use groupDatum as arg to ng-click -->
<button ng-click="nameAdd(groupDatum)">
Add
</button>
</div>
The nameAdd function:
$scope.nameAdd = function(groupDatum) {
var newId = uniqueId();
var newName = groupDatum.newName;
groupDatum.info.data.push({id: newId, name: newName});
}
try like this,
<div ng-repeat=“group in groups”>
<form>
<input type=“text” ng-model=“groups[$index].name” placeholder=“name” />
</form>
</div>
you also probably put the form tag outside of the repeater unless you want to create a new from for every input tag

Cascading select data binding

First look at my fiddle
JavaScript:
function CountryCntrl($scope) {
$scope.filters = {};
$scope.categories = [{
"id": 1,
"title": "Company",
"children": [{
"id": 2,
"title": "About",
"children": [{
"id": 6,
"title": "Company profile",
"children": [],
"isRoot": false
}],
"isRoot": false
} ..
}
HTML:
<div class="row" ng-controller="CountryCntrl">
<div class="col-lg-12">
<h4>Filter by:</h4>
</div>
<div class="col-lg-12">
<form>
<div class="row">
<div class="col-xs-4" ng-repeat="cat in categories" ng-if="cat.isRoot==true">
<div class="form-group">
<select ng-if="cat.isRoot==true" class="form-control" ng-model="filters.rootCat" ng-options="sub_cat.title for sub_cat in cat.children track by sub_cat.id">
<option value="">level 1 - {{$index}}</option>
</select>
</div>
<div class="form-group">
<select class="form-control" ng-model="filters[cat.id]" ng-options="sub_sub_cat.title for sub_sub_cat in filters.rootCat.children track by sub_sub_cat.id">
<option value="">level 2 - {{$index}}</option>
</select>
</div>
</div>
</div>
</form>
</div>
</div>
I'm not able to display the options of the select of the second level only, related to the first level.
In my fiddle you can see that you change the value of "level 1-0" the select below "level 2 - 0" is correctly populated but is binded the "level 2 - 6" too...
What's wrong ?
The problem is that you have an ng-repeat in which you use the same object as model for each item repeated, which means they will conflict and affect each other.
The simplest solution is probably to change filters.rootCat to filters['rootCat'+$index].
That way you ensure that each column of dropdowns have their own model.

Resources