update object using id in angular js - angularjs

I have an array with two keys like id and selected values its like below
$scope.overview =[{'id':1,'selectedvalues':[a,e,o]},{'id':2,'selectedvalues':[aa,ee,oo]},{'id':3,'selectedvalues':[aaa,eee,ooo]}];
I need to update after i am adding values 'h' for id =1 i need to update my array like
$scope.overview =[{'id':1,'selectedvalues':[a,e,o,h]},{'id':2,'selectedvalues':[aa,ee,oo]},{'id':3,'selectedvalues':[aaa,eee,ooo]}];
there is any other way in anuglar js currently i am handling in javascript like
if (this.selectedCategoryOverview.length > 0) {
for (var i in updateDropown) {
if (catid == updateDropown[i].id){
overviewUpdate = false;
updateDropown[i].selectedValues = tempSelectValuesArray;
}
}
}
if(overviewUpdate){
this.selectedCategoryOverview.push({
'id': catid,
'selectedValues': tempSelectValuesArray
});
}

Try to use array.find to find existing overview by id. If find method returns a value - just update the value, and add the value otherwise.
In pseudocode:
foundObject = array.find()
if(foundObject)
update()
else
pushNew()

It would not make much difference if you do it angular way or JS way unless DOM is involved, so here is one angular way which is nothing but cloated JS way,
function pushNewArrayValue(value){
angular.forEach($scope.overview,function(arr,i){
arr.selectedValue.push(value);
})
}
pusheNewArrayValue('h')

Try using filter,
var found;
if (this.selectedCategoryOverview.length > 0) {
found = $filter('filter')($scope.updateDropown, { id: catid });
if (found.length)
$scope.updateDropown = tempSelectValuesArray;
}
if (found && found.length) {
this.selectedCategoryOverview.push({
'id': catid,
'selectedValues': tempSelectValuesArray
});
}

Related

AngularJS: Apply filter to template

I created a simple filter to format a number based on the current locale.
angular.module('myApp').filter('doubleFilter', DoubleFilter);
function DoubleFilter($translate) {
return function(val, decimalPlaces) {
if (val && (typeof val === 'number')) {
val = val.toFixed(decimalPlaces);
if ($translate.use() === 'de_DE') {
val = val.replace('.', ',');
}
}
return val;
}
};
I call this filter in my template like this and it works fine:
{{dog.weight | doubleFilter : 2}}
However when I change the language using $translate.use('en_US') the format of the numbers in my template are not updated. Obviously I am missing out on something here.
How can I update the view when the language changes?
I think your directive needs to listen for 'local changed notification', for example :
scope.$on('$localeChangeSuccess', function () {
// code to execute the filter
});
Making your filter stateful may help ( see https://docs.angularjs.org/guide/filter )

AngularJS: searching data client side by custom filter

i am learning angular. so i am not good in angular. i am showing data in tabular format with the help of ng-repeat. i have one dropdown and textbox for filter data showing by ng-repeat. fields name are populated in dropdown. so user will select field name and put corresponding value in textbox and search will perform accordingly and data will be shown.
my code is working partially. basically some kind of problem is there in SearchList function. the problem is when trying to search by id then SearchList is not working properly. so looking for help. what to fix in the code. my js fiddle https://jsfiddle.net/tridip/rnoo3bqc/6/
$scope.SearchList = function(row) {
if ($scope.selectedFieldName && $scope.searchText) {
var propVal = row[$scope.selectedFieldName.toLowerCase()];
if (propVal) {
return propVal.toUpperCase().indexOf($scope.searchText.toUpperCase()) > -1;
} else {
return false;
}
}
return true;
};
working version url
https://jsfiddle.net/tridip/rnoo3bqc/8/
You need to convert the id's from number to string, e.g. by concatenating an empty string:
var propVal = row[$scope.selectedFieldName.toLowerCase()] + '';
the problem was with id that's a numeric field and hence toUpperCase() was failing for it.
if (propVal) {
propVal.toString().toUpperCase().indexOf($scope.searchText.toUpperCase()) > -1;
} else {
return false;
}

How to check if value already exists?

I have a small app that users can use to search for a movie, and then add it to their watchlist. Currently it is possible to add 1 movie multple times for the same user. Which ofcourse isn't expected behaviour.
My solution would be to find the unique id of the movie that's being added and crosscheck that with my movies_users data. If the movie_id value exists, do this, else do this.
At the moment I do have the unique movie id of the movie that's being added,
$scope.movieListID = response;
console.log ($scope.movieListID.id)
Which gets ouputted like a string, like so,
314365
And I got the movie records from the current user,
$scope.moviesCheck = response.data;
console.log ($scope.moviesCheck)
Which looks like this,
[{"id":2,"title":"Black Panther", "movie_id":"284054"}]
So what would be a good way to check if the result from $scope.movieListID.id already exists in the $scope.moviesCheck data?
* update *
Trying a suggestion below does not give the expected result.
var exists = function (id) {
$scope.moviesCheck.forEach(function (movie) {
console.log (movie.movie_id)
console.log (id)
if (movie.movie_id === id)
console.log ('duplicate')
else
console.log ('not duplicate')
});
}
exists($scope.movieListID.id);
The console.log output from this is,
312221
312221
not duplicate
Which clearly are duplicate results.
You can add a function in your controller to check if the movie exists in the list
var exists = function (id) {
$scope.moviesCheck.forEach(function (movie) {
if (movie.id === id)
return true;
});
return false;
}
// and call it
exists($scope.movieListID.id); // true or false
I'm not 100% if this is a good way to do this, but for me it works and I think it's pretty low on performance,
movieService.loadMovies().then(function(response) {
$scope.moviesCheck = response.data;
var arr = $scope.moviesCheck
function myIndexOf(o) {
for (var i = 0; i < arr.length; i++) {
if (arr[i].movie_id == o.exisitingMovie_id) {
return i;
}
}
return -1;
}
var checkDuplicate = (myIndexOf({exisitingMovie_id:movie.id}));
if (checkDuplicate == -1) {
From your question I've understood that, based on the object exists using id in the array of object, you have to do different action.
You can use $filter for this. Inject the filter for your controller and assign it to the scope. So this will be available whenever you want in this controller.
$scope.cFilter('filter')($scope.movies, {movie_id:$scope.existingMovie.movie_id}, true);
$sope.movies - is the list of movies passed to the filter. You can
send any list based on your need.
{movie_id:$scope.existingMovie.movie_id} - This one is the object
which one we need to find. This can be based on your need. Since we
are searching movie_id, we need to send the object with property
and value. {movie_id:$scope.existingMovie.movie_id}, Here movie_id is
the property and followed by the value with the colon.
true: This indicates that, to search exact matched values. By default
this is false. If this is set to false, then if we want to search 54
in the movie id, this will returns the objects whichever contains 54
as part of the value.
app.controller('controller', ['$filter',function($filter){
$scope.cFilter= $filter;
$scope.Exists=function(){
$scope.movies=[{"id":2,"title":"Black Panther", "movie_id":"284054"},{"id":3,"title":"Black Panther", "movie_id":"32343"},{"id":4,"title":"Black Panther", "movie_id":"98863"}]
$scope.existingMovie={"id":3,"title":"Black Panther", "movie_id":"32343"};
var _obj=$scope.cFilter('filter')($scope.movies, {movie_id:$scope.existingMovie.movie_id}, true);
if(_obj && _obj[0])
{
Console.log('object exists')
}
else
{
Console.log('Object is not found')
}
}
}])
Many Thanks Jeeva Jsb. This got me on the right track, however I thought I would clarify with a practical example that seems to work as expected.
So I have a function called getData which get the AJAX array but we need to check if the record exist before added to scope (else we get duplicates)
if (d.data.length) {
for (var i = 0; i < d.data.length; i++) {
var doesExist = $filter('filter')($scope.notifications, {NotifId:d.data[i].NotifId}, true);
if (doesExist.length == 0){
$scope.notifications.push(d.data[i]);
}
}
}
This should look familier...
when we are iterating through the returned AJAX object we need to check the ID of the (in my case notificiation)
var doesExist = $filter('filter')($scope.notifications, {NotifId:d.data[i].NotifId}, true);
This line creates a new array by filtering the existing array in scope ($scope.notifications) and passing in the same value from you interation.
If the value exists the object will be copied to the new array called doesExist.
A simple check of length will determine if the record needs to be written.
I hope this helps someone.

Backbone - trying to make a filter on a collection with nested object

i'm trying to filter a collection which has models with some nested object. Unfortunately, my result are always empty.
So my models returned in the collection are build like this:
My goal is simple:
I have a view with a list of tag and a content view with all the questions. When a user click on tag, for example, "c#", i want to filter my collection to just return questions with tag "c#"
Before i was doing a fetch on my server and it was working fine, but it was not optimize.
I already have a collection with all the questions so why make a new call, a filter is a better solution i think.
But i didn't succeded with my filter and i don't know if it's possible to do. For now i put my filter in my router because it's more easy to test.
i can't make a filter like this because i have an array of object
getQuestionsByTags: function(query) {
var test = this.questionsCollection.filter(function(model) {
return model.attributes.tags.name == query;
})
console.log('result');
console.log(test);
},
So i was thinking to make a loop but my result is always an empty array.
getQuestionsByTags: function(query) {
var test = this.questionsCollection.filter(function(model) {
_.each(model.attributes.tags, function(tag) {
return tag.name == query;
})
})
console.log('result');
console.log(test);
},
It's maybe simple, but i don't know what to do.
Thanks in advance :)
i've just found a solution that work.
getQuestionsByTags: function(query) {
var flag;
var test2 = this.questionsCollection.filter(function(model) {
flag = false;
_.each(model.attributes.tags, function(tag) {
if(tag.name == query) {
flag = true;
}
})
if(flag) {
return model.attributes;
}
})
console.log('result');
console.log(test2);
},
i put a flag. If he turn true inside the loop, the model has this tag so i return it.
I think it's not very conventional, so if someone have another solution, feel free to post it :)

Returning a collection list using a filter from an array of id in backbone.js

So I already got this working using a loop but is wondering is there is a cleaner way to do this.
Basically i got a model that got an array of ids from another model, currently I loop every id and add manually model to a new collection using this filter on the model collection.
getOneById : function(id){
return this.filter(function(data) {
return data.get("id") == id;
});
},
Is there a way to directly return a list doing something like
getAllById : function(arrayIds){
return _(this.filter(function(data) {
??????? return data.get("id") == eachID;
}));
},
Thanks!
you could reduce the looping by checking to see if the id of your object is at an index > -1 in the array:
function(arrayIds){
var models = _.select(collection, function(model){
return (_.indexOf(arrayIds, model.id) > -1);
});
return models;
}
this requires the inclusion of underscore.js in your code, but since you're already using backbone, you already have that.
My solution:
Having collection (Backbone.Collection) and arrayIds
var collection2 = new Backbone.Collection();
collection2.add(collection.models.filter(function(model){
return arrayIds.indexOf(model.id) !== -1;
}));
Four lines :D
console.assert(collection2.length === arrayIds.length) //OK

Resources