Avoid duplicates in a repeater are not allowed - angularjs

Is there any built-in feature on AngularJS to avoid ng-repeater to receive duplicated entries?
Right now I'm using the following code to prevent it:
$scope.tags = ['black','white','red','yellow','blue'];
$scope.selectedTags = [];
// textarea value
var words = $scope.message.split(' ');
for(var j = 0; j < words.length; j++) {
for (var k = 0; k < $scope.selectedTags.length; k++) {
if ($scope.selectedTags[k].Name == words[j]) {
contains = true;
}
}
if (!contains)
{
$scope.selectedTags.push($scope.tags[i]);
contains = false;
}
}

Angular UI has a unique filter:
Filters out all duplicate items from an array by checking the specified key
Alternatively, if it's just a string array you can filter your array like:
arr.filter(function (e, i, arr) {
return arr.lastIndexOf(e) === i;
});

Related

iterating inside a $http.get

I've this block of code which displays 20 items per request.
.controller('ActorController',function($scope,$http) {
$scope.getActors = function () {
var actors = $http.get(https://api.themoviedb.org/3/person/popular&page=1);
actors.then(
function (response) {
$scope.actors = response.data.results;
}
);
}
})
Instead of page=1, if i put page=2, I'll get another set of 20 items and so on. How to iterate inside the $http.get if I want more than 1 get request in a single page? I want to display the 2nd 20 items after displaying the 1st 20.
So you're saying that you want to make multiple calls to $http.get in a loop? If so you'd do something like this:
.controller('ActorController',function($scope,$http) {
$scope.getActors = function () {
for(var i = 0; i < 5; i++) {
getPage(i);
}
}
function getPage(i) {
var actors = $http.get('https://api.themoviedb.org/3/person/popular&page=' + i);
actors.then(function (response) {
for(var j = 0; j < response.data.results.length; j++) {
$scope.actors.push(response.data.results[j]);
}
});
}
})
That will put the data for the first 5 pages into the $scope.actors array.
you can use $q.all to send multiple http requests at once
var fulAr = [];
for (var i = 1; i <= 2; i++) {
fulAr.push($http.get("https://api.themoviedb.org/3/person/popular&page=" + i))
}
$q.all(fulAr).then(function(response) {
console.log(response[0].data) //page 1 content
console.log(response[1].data) //page 2 content
for(var j = 0; j < response.length; j++) {
$scope.actors = $scope.actors.concat(response[j].data.results);
}
})
Make sure to inject $q to controller

How to delete the array with index 2 in local storage?

My local storage looks like this
{"data":[[0,"Post1","Text1","2016-12-16T11:01:00.000Z"],[1,"Post2","Text2","2016-12-20T14:00:00.000Z"]],[3,"Post3","Text3","2016-12-25T13:00:00.000Z"]]}
How can I delete only one item in the array?
I have tried with this, where postid is the array index I want to delete.
var postid = 1
var info = JSON.parse(localStorage.getItem("rp_data"));
var obj = [];
for(var i = 0; i < info.data.length; i++){
var data = info.data[i];
if(data === postid){
info.splice(i, 1);
}
}
localStorage.setItem("rp_data", JSON.stringify(data));
So the if part is wrong I guess!?
Any input appreciated, thanks.
UPDATE
So with this I can remove one of the posts in the array, where the first item in the array is equal to my postid, so if the postid=1 it will remove the second post in the array.
//var postid = $$(this).attr('data-id');
//postid=parseInt(postid)
postid=1
var info = JSON.parse(localStorage.getItem("rp_data"));
//remove object
for(var i = 0; i < info.data.length; i++){
var data = info.data[i][1];
myApp.alert(data);
if(i === postid){
myApp.alert(i);
info.data.splice(i, 1);
}
}
localStorage.removeItem("rp_data");
localStorage.setItem("rp_data", JSON.stringify(info));
So I have 1 more problems.
If I use postid=1 as above it works and it creates a new local storage with the right values. But if get the value from my form and then try to convert the string to a number it stops working.
This does not work, like it is not converting the string to a number?
var postid = $$(this).attr('data-id');
postid=parseInt(postid)
So why is this not converting it to a number?
Since the items in the array are JSON objects, you cannot compare the object to postid. You should use indexOf. You also don't want to splice the index. This should be the object or item in this case. If you want to remove the item in the object, you would have to iterate through the object as well. So this would be a nested loop.
//remove object
for(var i = 0; i < info.data.length; i++){
var data = info.data[i];
if(i === postid){
info.data.splice(data, 1);
}
}
//remove item in object
for(var i = 0; i < info.data.length; i++){
if(i == postid){
for(var j = 0; j < info.data[i].length; j++){
var item = info.data[i][j];
info.data[i].splice(item,1);
}
}
}

How can I push element in an array whenever a function get called?

I am implementing infinite scroll. I Have an array named hotels which gets data from $http.get() method. Now I want to populate a new array named hotelsNew[] with the value of hotels array. But I want to push value in the hotelsNew incrementing value of m and j.
The value of m and j need to be updated (increment) whenever function loadMore() is called. Initial value of m is 0 and j is 5. When loadMore() gets called, again m will be 5 and j will be 10 and so on.
I am unable to save value of m and j anywhere because $http.get() is asynchronous. Is there any proper way to save values of m and j, and reuse it when loadMore() gets called again?. Maximum j value is 40. and when m = j(40), it will stop.
Here is my controller code.
$scope.loadMore = function() {
$http.get(url).success(function(data, status, headers, config) {
if(data) {
$scope.hotels = data.hotels;
for(var i = m; i < j; i++) {
console.log('i=',i);
$scope.hotelsNew.push($scope.hotels[i]);
console.log('hotelsNew',$scope.hotelsNew);
}
}
}
How can i increment m and j value ?any idea?
If m and j increments same amount each time, you can create a local variable in your controller.
var m = 0, j = 5;
$scope.loadMore = function() {
$http.get(url).success(function(data, status, headers, config) {
if(data && j < 40) {
$scope.hotels = data.hotels;
for(var i = m; i < j; i++) {
console.log('i=',i);
$scope.hotelsNew.push($scope.hotels[i]);
console.log('hotelsNew',$scope.hotelsNew);
}
m += 5;
j += 5;
}
}
}
Use a promise to avoid async call
$scope.loadMore = function() {
$http.get(url).then(function(data) {
if(data) {
$scope.hotels = data.hotels;
for(var i = m; i < j; i++) {
console.log('i=',i);
$scope.hotelsNew.push($scope.hotels[i]);
console.log('hotelsNew',$scope.hotelsNew);
}
}
}
see the example for pushing array:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.push("Kiwi");
get length of data using
$s=Array.sizeof($data)
for($i<0;$i<=$s;$i++){//task here}

Angular values update in both elements

I am adding same element (json object) into a list (from another list) twice using .copy to break the reference. But even after doing that when I change some values in one both of them are getting updated.
$scope.addProduct = function (item) {
var index = $scope.itemsProduct.indexOf(item);
$scope.scopItem = {};
angular.copy(item , $scope.scopItem);
for(var j in $scope.scopItem['ABC']) {
$scope.scopItem['ABC'][j].dataType='Discount';
$scope.scopItem['ABC'][j]['Discount'] = '';
}
if (index != -1) {
$scope.itemsTags.push($scope.scopItem);
$timeout(function() {
$scope.$apply(function () {
$scope.calculate($scope.scopItem);
});
}, 10);
}
};
$scope.calculateParam = function (indexQ) {
var index = $scope.itemsTags.indexOf(indexQ);
$scope.itemsTags[index]['ABC']['Discount'] = '10'; //or some other logic
}
Need help as even i am not adding the same element(using .copy) and updating the "Discount" property of one updates both??
Note: ABC is a inner list with property as "Discount" and I am changing "Discount"
Some comments:
for(var j in $scope.scopItem['ABC'])
it's absolutely incorrect and should be rewrited to
for(var j=0; j < $scope.scopItem['ABC'].length; j++)
also scopItem is changed in calculate method and stored in itemsTags

Splice array within array

How can I splice an array within another array?
I'm trying to create a game for kids in my class. Some kind of a trivia history question creator. How to splice the MasterArray so that I would get rid of sub-arrays (Hard-England and Medium-England) within the allEnglandArray. Because the "MasterArray.splice()" seem to be affecting - splicing only the allEngland array, or the allFrance array. But I need to get rid of those sub-arrays...
My code:
var Easy-England:Array = ["item1","item2","item3","item4","item5"];
var Medium-England:Array = ["item6","item7","item8"];
var Hard-England:Array = ["item9","item10"];
var allEngland:Array = [Easy-England,Medium-England,Hard-England];
var Easy-France:Array = ["item11","item12","item13","item14","item15"];
var Medium-France:Array = ["item16","item17","item18"];
var Hard-France:Array = ["item19","item20"];
var allFrance:Array = [Easy-France,Medium-France,Hard-France];
// the list of countries goes on and on and on... (Italy, Hungary, etc.)
var allStuff:Array = [allEngland, allFrance, etc.];
var MasterArray:Array;
// FUNCTIONS
// clear MasterArray - first I clear out completely the MasterArray
function clearMasterArray():void
{
MasterArray.splice(0);
}
// update MasterArray - than I fill the MasterArray with data according to checkBoxes
function updateMasterArray():void
{
for (var i:int = 0; i<checkBoxBlock.myCheckBoxes.length; i++)
{
if (checkBoxBlock.myCheckBoxes[i].selected)
{
MasterArray.push(allStuff[i]);
}
}
}
// splice MasterArray - last thing I do is splice the items according to student's proficiency level, referred to as "studentPL".
function spliceMasterArray():void
{
if (studentPL == 1)
{
for (var i:int = 0; i<allStuff.length; i++)
{
allStuff[i].splice(5,5);
}
}
if (studentPL == 2)
{
for (var i:int = 0; i<allStuff.length; i++)
{
allStuff[i].splice(8,2);
}
}
if (studentPL == 3)
{
for (var i:int = 0; i<allStuff.length; i++)
{
trace("no need to splice");
}
}
}
And after this I call those functions in another function in this order...
function creatorFunction():void
{
clearMasterArray();
updateMasterArray();
spliceMasterArray();
}
Instead of:
var allEngland:Array = [Easy-England,Medium-England,Hard-England];
try this:
var allEngland:Array = Easy-England.concat(Medium-England, Hard-England);
This way you will have a 'flat' array (no sub-arrays), so it will be easier to deal with.

Resources