Generate new $$hashkey on angular push - angularjs

I want to push an item in my array object, and this is my code:
<li gridster-item="item" ng-repeat="item in widgets" style="border: #ddd 1px solid;">
<a ng-click="list.push(item)" style="padding:2px;position: absolute;z-index: 1000;right:2%;top: 2%;" class="add-widget-to-sidebar pull-right">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true" style="margin:2px 10px;"></span>
</a></li>
and $scope.widgets already has hashkeys on every object, and what I want to do is every time I push a new item in my list, I want a new $$hashkey for it. I already tried doing this and it didn't work:
$scope.$watchCollection('list', function() {
$scope.temp = []
rand=0;
angular.forEach($scope.list,function(value,key){
value.$$hashKey = rand++;
console.log(rand);
$scope.temp.push(value);
});
$scope.list = $scope.temp;
console.log('temp');
console.log($scope.temp);
console.log('list');
console.log($scope.list);
$scope.resize();
});

I found an alternative solution:
<ul>
<li ng-repeat="item in widgets track by $id($index)">
.....
</li>
this will remove $$hashkey on your ng-repeat

Related

Vuejs creating a list from an array

I'm having a strange problem creating a list with Vuejs. I have an array like so:
const sr = new Vue({
el: '#singlerecipe-app',
data: {
checkeditems: [],
},
});
And this is instantiated in my HTML like so:
<div class="container" id="singlerecipe-app">
<singlerecipe :checkeditems="checkeditems"></singlerecipe>
</div>
And declared as a Prop in my component:
Vue.component('singlerecipe', {
props: ['checkeditems'],
template: `
<ul>
<li v-for="item of checkeditems">
{{ item.checkeditems }}
</li>
</ul>
`
})
The checked items code is:
<li v-if="result.strIngredient1">
<input type="checkbox" :value="result.strIngredient1" :id="result.strIngredient1" v-model="checkeditems"> {{result.strIngredient1}} - {{result.strMeasure1}}
</li>
<li v-if="result.strIngredient2">
<input type="checkbox" :value="result.strIngredient2" :id="result.strIngredient2" v-model="checkeditems"> {{result.strIngredient2}} - {{result.strMeasure2}}
</li>
If I click on one of the checkbox it definitely adds the correct value to the array checkeditems[] but oddly, it creates the new list items but doesn't add the value so I end up with this:
<ul>
<li></li>
<li></li>
</ul>
With no value in the list item. Does anyone have any idea what I'm doing wrong?
I think you've just accidentally added a 'checkeditems' in.
It should be:
Vue.component('singlerecipe', {
props: ['checkeditems'],
template: `
<ul>
<li v-for="item of checkeditems">
{{ item }}
</li>
</ul>
`
})

Grabbing value from nested json array with Angular

I'm having trouble accessing the artists array within the items array here to be able to render the name field:
I'm currently able to grab other values at the same level as the artists that are simple objects. How can I loop through the array of the nested array?
Controller
$scope.search = "";
$scope.listLimit = "10";
$scope.selectedSongs = [];
$scope.addItem = function(song){
$scope.selectedSongs.push(song);
}
function fetch() {
$http.get("https://api.spotify.com/v1/search?q=" + $scope.search + "&type=track&limit=50")
.then(function(response) {
console.log(response.data.tracks.items);
$scope.isTheDataLoaded = true;
$scope.details = response.data.tracks.items;
});
}
Template
<div class="col-md-4">
<div class="playlist">
<h3>Top 10 Playlist</h3>
<ul class="songs" ng-repeat="song in selectedSongs track by $index | limitTo: listLimit">
<li><b>{{song.name}}</b></li>
<li>{{song.artists.name}}</li>
<li contenteditable='true'>Click to add note</li>
<li contenteditable='true'>Click to add url for image</li>
</ul>
<div id="result"></div>
</div>
</div>
You should do another ng-repeat to access the artists,
<div class="songs" ng-repeat="song in selectedSongs track by $index | limitTo: listLimit">
<ul ng-repeat="artist in song.artists">
<li><b>{{song.name}}</b></li>
<li>{{artist.name}}</li>
<li contenteditable='true'>Click to add note</li>
<li contenteditable='true'>Click to add url for image</li>
</ul>
</div>

Angular expression in ng-repeat and ng-click

I am trying to call a function using ng-click which is dynamically generated by ng-repeat the problem is that i am not able to get the parameter value passed in ng-click function. My html code is
<div class="col-md-4 col-xs-12 col-lg-4" ng-repeat="(key, value) in uploadedFiles">
<b>value.filename is {{value.filename}}</b>
<img ng-if="value.filetype=='jpg'" ng-src="http://localhost:3000/uploads/{{value.filename}}" class="img img-responsive thumbnail uploadedfile-thumb"/>
<img ng-if="value.filetype=='PDF'" ng-src="images/pdf-thumb.jpg" class="img img-responsive thumbnail uploadedfile-thumb"/>
<a ng-href="http://localhost:3000/uploads/{{value.filename}}" target="_blank" class="uploaded-file-links">View</a>
<a ng-href="#" ng-click="deleteFile(value.filename);" class="uploaded-file-links">Delete</a>
</div>
i am not getting the filename which is passed in deleteFile(), bit it is working in <b> tag in 2nd line so finally this is a problem with my angular expression so how should i write it?
I will try to make some guessing here.
I suppose that your uploadedFiles is an array of objecs, and not an object itself. In that case, you should use ng-repeat="file in uploadedFiles" which is meant to iterate over array elements. This will iterate over your array and assignf the corresponding object for that iteration to file variable.
The ng-repeat="(key, value) in uploadedFiles" is meant for iterating over object properties instead of iterating over array elements. For example, if uploadedFiles is:
var uploadedFiles = {
prop1: 'value1',
prop2: 'value2',
prop3: 'value3'
};
and you iterate over it like this:
<ul>
<li ng-repeat="(key, value) in uploadedFiles">
{{value}}
</li>
</ul>
you would get the following output:
value1
value2
value3
But if uploadedFiles is an array like this one:
var uploadedFiles = [
{
prop1: 'value11',
prop2: 'value12',
},
{
prop1: 'value21',
prop2: 'value22',
},
{
prop1: 'value31',
prop2: 'value32',
}
];
And you iterate over it like this:
<ul>
<li ng-repeat="file in uploadedFiles">
{{file.prop1}}
</li>
</ul>
you would get:
value11
value21
value31
So in your case, I would try the following:
<div class="col-md-4 col-xs-12 col-lg-4" ng-repeat="file in uploadedFiles">
<b>file.filename is {{file.filename}}</b>
<img ng-if="file.filetype=='jpg'" ng-src="http://localhost:3000/uploads/{{file.filename}}" class="img img-responsive thumbnail uploadedfile-thumb"/>
<img ng-if="file.filetype=='PDF'" ng-src="images/pdf-thumb.jpg" class="img img-responsive thumbnail uploadedfile-thumb"/>
<a ng-href="http://localhost:3000/uploads/{{file.filename}}" target="_blank" class="uploaded-file-links">View</a>
<a ng-href="#" ng-click="deleteFile(file.filename);" class="uploaded-file-links">Delete</a>
</div>

How to show object in array angular?

How to show comments in items?
This is where items save
$scope.items = [
{ 'item': 'one',
'comments':[{'comment':'comment'}]
},
{ 'item': 'two',},
{'item': 'three'}
];
<ul>
<li ng-repeat="ite in items">
{{ite.item}} {{ite.comments.length}}
<button ng click="remove($index)">Remove</button> <div ng-repeat="c in ite.comments">{{c.comment}}</div>
</li>
</ul>
http://plnkr.co/edit/19w1Q3XhoWQcpxm5SuxX?p=preview
You Just missed to add your comment Div in between the list tag. please update the code like above code. I have checked on Plunker.
<li ng-repeat="ite in items">
{{ite.item}} {{ite.comments.length}}
<button ng-click="remove($index)">Remove</button> <div ng-repeat="c in ite.comments">{{c.comment}}</div></li>

ng-repeat li's based on nested data, but without nesting the li's

This is my data structure:
headings = [
{name:'H1', items: ['a', 'b', 'c']},
{name:'H2', items: ['d', 'e', 'f']}
];
I want to achive this:
<li ng-repeat="heading in headings" class="heading">{{ heading.name }}</li>
<li ng-repeat="item in heading">{{ item.name }}</li>
But in the second ng-repeat, heading does not exist. At the same time, I don't want to nest the second li inside of the first one.
Is this solvable?
I'm thinking some kind of comment solution, but I guess this is knockout syntax:
<!-- ng-repeat="heading in headings" -->
<li class="heading">{{ heading.name }}</li>
<li ng-repeat="item in heading">{{ item.name }}</li>
<!-- end-repeat -->
You can use ng-repeat-start and ng-repeat-end:
<li ng-repeat-start="heading in headings" class="heading">{{ heading.name }}</li>
<li ng-repeat="item in heading.items" ng-repeat-end>{{ item }}</li>
Working Fiddle
ng-repeat-start repeats everything up until and including the element with ng-repeat-end.
You could flatten them:
$scope.$watch('headings', function(headings) {
$scope.flattened = [];
angular.forEach(headings, function(heading) {
angular.forEach(heading.items, function(item) {
$scope.flattened.push({
heading: heading,
item: item
});
});
});
});
Then in your HTML:
<li ng-repeat="flat in flattened">{{flat.item.name}}</li>
You can wrap the lis with an additional element and put ng-repeat on that element. If you have no other li items in the list, just put the ng-repeat on the list:
<ul ng-repeat="heading in headings">
<li class="heading">{{ heading.name }}</li>
<li ng-repeat="item in heading.items">{{ item }}</li>
</ul>
See this Plunker for a runnable example.

Resources