AngularJS Assign an object by its property to the ng model - javascript

I'm kind of new to angularJS
I have code; all of it is wrong.
I'm creating a json object with options.
I have a json object called "match" with a property "lineup".
When you check the checkbox for any player, you add this player to the lineup property like:
lineup:[{uid:1,pos:0},{uid:2,pos:0}]
What I want to know is how can I assign the select to an specific item in the lineup array. In example, if I change the select for the player 1, then lineup would change to:
lineup:[{uid:1,pos:2},{uid:2,pos:0}]
Btw, I know I can use ng-options for the select directive, but this is the last code I got before coming here.
<ul class="list-group" ng-if="match.formation > 0">
<li class="list-group-item" ng-repeat="p in players track by $index">
<input type="checkbox" ng-model="p.lineup"
ng-change="setLineup(p,$index)"
ng-disabled="match.lineup.length > 10 && (p.lineup == 0 || !p.lineup)" />
{{p.player}}
<select ng-model="" class="pull-right">
<option ng-repeat="e in NotSelectedPosition() track by $index"
value="{{e.id}}">{{$index+1+'.- '+e.name}}</option>
</select>
</li>
Edit:
players is a json object as well:
$scope.players = [{uid:1,lineup:false,name:'player1'},
{uid:2,lineup:false,name:'player 2'},etc
];
formation is just an integer value

Bind it with p.uid not p.lineup beacuse you are using ng-repeat="p in players track by $index", which means you get the objects in an array one by one.

Related

If all array items are hidden show another div in AngularJS

I'm using ng-repeat on my page. ng-class working very well.
<div class="card news" ng-repeat="item in news track by $index" id="{{news.nid}}" ng-init="parentIndex = $index" ng-class="{hidden: '{{getCheck($index)}}' == 'true'}">
...
</div>
Now I need, if all items are hidden, show this div:
<h3 class="news-empty">No news</h3>
Whats the rules? How can I do it? Thanks.
You need another method that checks if all elements are hidden:
$scope.everythingIsHidden = function() {
return $scope.news.every((new, index) => $scope.getCheck(index));
}
$scope.getCheck = function(index) { // Your getChek function that I suppose it checks if an element is hidden based on index
//...
}
<h3 class="news-empty" ng-if="everythingIsHidden()">No news</h3>
TheCog's answer will work. If you want to do this in a more 'Angular' way you're going to need to refactor what you have.
You shouldn't be trying to hide them with a CSS class. ngRepeats have a built in filter syntax. So, you should be filtering them out.
<div class="card news"
ng-repeat="item in news | filterMethod as results track by $index"
id="{{news.nid}}"
ng-init="parentIndex = $index"
>
<h3 class="news-empty" ng-if="results.length === 0" >No news</h3>
The as results statement in the repeat will store the filtered array in results. filterMethodneeds to be an angular filter and it will probably work similarly to your getCheck($index) method.
You want to add an ngShow to the h3 tag, and aim it at a function you write in your controller that checks if the array is empty, probably by iterating over the same array that's hidden and running getCheck($index) on each.

track by $index isn't solving dupes error

I am trying to iterate through an array of objects and display them in my HTML using Angular. I have done this before without any problems by using "track by $index". But the standard error is still raised:
Error:
[ngRepeat:dupes] http://errors.angularjs.org/1.3.15/ngRepeat/dupes?p0=(key%2C%20value)%20in%20n&p1=string%3Ab&p2=b
But I have already added track by $index. I am confident there isn't any issue requesting the data as I have been able to display it correctly.
<div ng-repeat="n in post.userData.bookmarks track by $index" >
<div ng-repeat="(key, value) in n">
<div>{{ key }}</div>
</div>
</div>
Suggestions?
Dataset:
bookmarks: [{"1234": "Title1"}, {"5678": "Title2"}]
What happens is that a user bookmarks a post that they want to read later. I save the post id and the title of the post to an object and store this in an array. (I actually just wanted to store it to an object like so: {"1234": "Title1", "5678": "Title2"}, but couldn't figure it out with mongodb, since it doesn't seem to let you save as object data type.)
Then I want to ng-repeat the user's bookmarks in their profile. The only way I know how to do this is to iterate through the array and then iterate through each object. Of course, there is only one item in each object. But this is why I have the second ng-repeat. But when I do track by $index for both, as one of the answers lists below, it still doesn't give the desired behavior.
Something that could be causing a problem is that I also have a sort of dashboard that can be viewed on the side while viewing any given post. And on the dashboard they should be able to see their bookmarks. Also if they are on a post that they have bookmarked, if they click a (un)bookmark button on the post, it should automatically remove that bookmark on their bookmark dashboard.
But none of the suggestions have worked.
You forgot another ng-repeat: <div ng-repeat="(key, value) in n track by $index">
I don't know Why u write two times repeat
<div ng-repeat="n in post.userData.bookmarks track by $index" >
<a ng-href="/tuts/{{n.key}}">{{ n.key}}</a>
</div>
OR
<div ng-repeat="(key,value) in post.userData.bookmarks track by $index" >
<a ng-href="/tuts/{{value}}">{{ value}}</a>
</div>
key is anything which you get from object.

Pass parsed ng-repeat data into function

Currently I'm using a ng-repeat to go over some json data to produce an unordered list. I have a ng-click handler on each list item, which when clicked I need to gather all the data from the current list item clicked (including the item.things (array)) and send it over to a below referenced 'delete' function.
I thought passing $event would do it but I can't seem to find the data in it.
Example:
<ul>
<li ng-repeat="item in items" ng-click="delete($event)">
{{item.id}}
<span ng-repeat="thing in item.things">
{{thing.id}}
</span>
</li>
</ul>
Which produces:
Item 1
Thing X
Thing Y
Item 2
Thing X
Thing Y
..etc etc
<li ng-repeat="item in items" ng-click="delete(item)">
This should work.

Setting value in controller works, but setting value in angular expression doesn't?

The following code doesn't work -
<div ng-init="selected=-1">
<ul ng-repeat="x in arr">
<li ng-click="selected = $index">...</li>
</ul>
When I click on one of the lis, the variable selected remains as -1. But the following does work -
<div ng-init="selected=-1">
<ul ng-repeat="x in arr">
<li ng-click="setTo($index)">...</li>
</ul>
$scope.setTo = function(index){selected = index;}
Why is that? Nothing functional seems to have changed.
ng-repeat directive creates it's own scope for each item in arr, so when expression selected = $index is executed, the new property selected is created on that scope, at the same time parent scope remains untouched.
Is why your selected property does not change in the first case.
Since the ngRepeat directive creates its own scope, you need to refer to $parent.selected in the first example:
<li ng-click="$parent.selected = $index">
http://plnkr.co/edit/9iUgp57KwvrlC3TDO3YC?p=preview

Angularjs : What is the best way to let Binding Data later update

If I have a ng-repeat directive bind with my initial data,
<!-- list 1-->
<li ng-repeat="data in datas">{{data.name}}</li>
and I change the data by another ng-repeat and ng-model directive,
<!-- list 2-->
<li ng-repeat="data in datas">
<input type="text" ng-model="data.name">
</li>
In Angular way, any method can do list 1 ng-repeat data refresh not immediately (after I click a Save button)?
<button ng-click="save()">Save</button>
You can use a second (temporary) clone to make the changes and copy the changes over to the actual object using angular.copy.
The actual list:
<ul><li ng-repeat="item in items">
{{item.name}} (id: {{item.id}})
</li></ul>
Edit the list:
<ul><li ng-repeat="item in tempCopy">
<input type="text" ng-model="item.name" />
</li></ul>
<button ng-click="persistChanges()">Save</button>
<button ng-click="discardChanges()">Discard</button
In your controller:
/* Persist the changes */
$scope.persistChanges = function () {
angular.copy($scope.model.tempCopy, $scope.model.items);
};
/* Discard the changes */
$scope.discardChanges = function () {
angular.copy($scope.model.items, $scope.model.tempCopy);
};
See, also, this short demo.
Finally, there is a similar example on the Angular docs on angular.copy.
It seems you are creating new items within datas by extending the array by one element? If this is so, why not use a different model for the form and push the result onto the array data when the save button is clicked?
Similarly, when editing an item, clone the array element and make it the model for the resulting form, then modify the original array element when the save button is clicked.

Categories

Resources