d8ta d8ta - 9 days ago 5
Javascript Question

Compare two arrays and using ng-style to mark equal entries in the arrays

I have a list which shows a query of words from a db, from there i can click on one word and it gets pushed to another list which i can save than. With this i can create different wordlists. What i want to do is to give the words another color if i have already pushed them on my new list.

To do so i use a function in my controller to compare the two lists with and angular.foreach. If wordFromQuery._id === wordOnNewList._id i gave the words another background color with ng-style.

Here is my code:

View

ng-repeat="word in searchWords" ng-click="addWordToSet(word)" ng-class="isInside(word)" ng-style="{ background: choosenWords.value == 'exist' ? 'lightgreen' : 'white' }"


I iterate over the words query (searchWords) and with addWordtoSet(word) i push them to my other array (this works great). isInside(word) will do the angular.foreach to compare the two arrays and the ng-style should provide different styles, according to the if-statement from the isInside function.

Controller

$scope.isInside = function (word) {
angular.forEach($scope.currentWordlist, function (item) {
if (item._id === word._id) {
$scope.choosenWords = {value: 'exist'};
} else {
$scope.choosenWords = {value: 'notOnList'};
}
});
};


The angular.forEach compares the words from both arrays. currentWordList is the array in which i push with addWordToSet

What happens is that one word on the searchword array gets the green color (and its set of by +1, so if the word in arraypos. 0 would be right the arraypos. 1 gets the green color).

I suspect that i did it all wrong with the ng-class element, but i didnt found another good opportunity to get the word._id another way. Did i do something obviously wrong here?

I would appreciate tips or hints. Thanks!

UPDATE

It works quite fine with the addWordToSet function:

$scope.addWordToSet = function (word) {
var exists = false;
angular.forEach($scope.currentWordlist, function (item) {
if (item._id === word._id) {
exists = true;
}
});
if (exists === false) {
$scope.currentWordlist.push(word);
}
};


The only thing i need i think is not doing this on click but instantly without clicking anything. is
my ng-class="isInside(word)"
the right choice for that?

Answer

I sat together with a friend and we came up with a working version of this problem, so here is the solution in case someone has a similar problem and hand.

In the Controller we used the following function:

    $scope.isSelected = function (word) {
      var found = false;
      angular.forEach($scope.currentWordlist, function (item) {
        if (item._id === word._id) {
          found = true;
        }
      });
    return found;
    };

It uses the foreach to compare the arrays and if there are ids that are a match the found bool returns true.

In the View we used the following:

ng-class="isSelected(word) ? 'marked' : 'unmarked'"

which uses the marked or unmarked css class for, in my case, coloring the matched words in green (marked). All other words are getting the background color white.

here is the CSS:

.marked {
  background: $lightgreen;
}

.unmarked {
  background: $nicewhite;
}

In my case i use scss and colorvariables, but you can, of course use all other colors like red; or #fff. The result of this are two arrays that are views. The first one is a searchquery from a DB which shows all words. The second is a new array in which you can push words by clicking on one of the words. If you do so the word gets pushed AND it gets a green background. Thats it, i hope this is good information.