forEach loop check | AngularJS - angularjs

// Check voted
var votes = res.data.votes;
if(votes.length == 0){$scope.like = true;}
votes.forEach(function(vote){
if(vote.userId === auth.profile.user_id) {
$scope.liked = true;
} else {
$scope.like = true;
}
});
I have written a code to check if the user has voted or not, but I'm having a small issue with the else statement:
using the following code, the $scope.liked works correctly, but the else statement only goes for the first.
How can I edit this, so he goes through all the votes, and if nothing is found, he displays the $scope.like

What about just do it outside the loop?
votes.forEach(function(vote){
if(vote.userId === auth.profile.user_id) {
$scope.liked = true;
}
});
$scope.like = !$scope.liked;

Related

How to implement a for loop with if statements

for (let i = 0 ; i<user.length;i++)
{
if (this.username === user[i].username && this.password === user[i].password){
this.title="Successfully login your account";
this.router.navigate(['/home']);
return;
} else {
this.title = "Please check your username and password (or) create New Account in Register";
return;
}
}
return user[i];
}
your else statement should not be in the loop. you else statement will execute as soon as you hit the first user. set a userVerifiedFlg = false; before the loop, and then check to see if it is still false after checking against all users.

using lodash _find to return true or false

I'm trying to use lodash function to find if it satisfies the if statement. When the code has run the code which 'return false', it stills continue execute the _find function and did not return the result (boolean value) in the scope.onToggle.
$scope.onToggle = function(disposition) {
if (requiredFieldsEntered()===false){
// if return value from the function is false, alert user
}
}
function requiredFieldsEntered(){
var res = _.find($rootScope.CustomFields,
function(field){
if(field.enabled && field.required){
if(field.table_name === 'session'){
if(!$scope.session.external_id){
console.log(field.column_name);
return false;
}
else if (field.table_name === "session_extension"){
if(!$scope.session.extension|| ($scope.session.extension && !$scope.session.extension[field.column_name])){
console.log(field.column_name);
return false;
}
}
}
}});
if (res) return false;
else return true;
}
First let's stop and consider what _.find actually does. It loops over an array and returns the first element of the array that matches the condition.
_.find([1, 2, 3, 4], function(num) { return num % 2 === 0 });
// returns 2
In the case of your _.find function, then, you'll either get back one of the fields from $rootScope.CustomFields or undefined if none of the fields returns a truthy value from function(field)….
Here is where you have your problem. The anonymous function function(field)… only ever returns false. You need to return true if you find an error, or else return false otherwise.
Since your requiredFieldsEntered() function is ultimately trying to return either true or false, you can decide which of those to return based on whether or not your _.find function returns some object or undefined.
Something like this:
$scope.onToggle = function(disposition) {
if (requiredFieldsEntered()===false){
// if return value from the function is false, alert user
}
}
function requiredFieldsEntered(){
const fieldWithErrors = _.find($rootScope.CustomFields,
function(field){
let result = true;
if(field.enabled && field.required){
if(field.table_name === 'session'){
if(!$scope.session.external_id){
console.log(field.column_name);
result = false;
} else if (field.table_name === "session_extension"){
if(!$scope.session.extension|| ($scope.session.extension && !$scope.session.extension[field.column_name])){
console.log(field.column_name);
result = false;
}
}
}
}
return result;
});
if (fieldWithErrors) {
return false;
}
return true;
}
Quick note that a shorter but somewhat less-readable version at the end may replace this bit:
…
if (fieldWithErrors) {
return false;
}
return true;
}
With:
…
return !!!fieldWithErrors;
The first two exclamation points would be typecasting the result of your find function to either true if it comes up with something or false if it returns undefined, and then the third exclamation point would invert that boolean to match your current scheme of returning false if there are errors.
(Or you could change your function name to errorsArePresent and return true – !!fieldWithErrors).

break a forEach with angularJS

I need some help. I have 2 loops to traverse two lists of records . The thing is that at some point should put a break or something, because the last loop crushes the value I'm looking for.
This is my code
for (var i in $scope.users) {
for (var j in $scope.states) {
if ($scope.users[i].id === $scope.states[j].user) {
if ($scope.states[j].estado === 'totallyBussy') {
$scope.users[i].estado= 'Not available';
} else if ($scope.states[j].estado === 'partlyBussy') {
$scope.users[i].estado= 'Maybe available';
}
}
else {
$scope.users[i].estado= 'Available';
}
}
}
Where user 4 and user 5 should be 'Maybe available' and 'Not available', but with this code, I'm getting 'Available for user 0, 1, 2, 3, and the last one. And the last one is crushes with else.
I hope I explained well.
Thanks so much
You can use the break keyword, which will end the loop when executed.
One side note: you don't want to use for (var i in array) {} since you may iterate through Array properties (and have i take unexpected values).
I updated your code with a more reliable iteration.
for (var i = 0, il = $scope.users.length; i < il; i++) {
var user = $scope.users[i];
for (var j = 0, jl = $scope.states.length; j < jl; j ++) {
var state = $scope.states[j];
if (user.id === state.user) {
if (state.estado === 'totallyBussy') {
user.estado = 'Not available';
} else if (state.estado === 'partlyBussy') {
user.estado = 'Maybe available';
}
// Go to the next user (break the "states" loop)
break;
} else {
user.estado = 'Available';
}
}
}
EDIT: If $scope.users and $scope.states are not Arrays but actually Objects (which would seem strange to me but anyway), you can keep for (var i in object) {} but you have to add a check: if (object.hasOwnProperty(i)) {} in the loop.
you can add a flag which will become true when you got your desired value.
something like
var gotValue = false;
for (var i in $scope.users) {
if(!gotValue)
{
for (var j in $scope.states) {
if ($scope.users[i].id === $scope.states[j].user) {
if ($scope.states[j].estado === 'totallyBussy') {
$scope.users[i].estado= 'Not available';
gotValue = true;
} else if ($scope.states[j].estado === 'partlyBussy') {
$scope.users[i].estado= 'Maybe available';
gotValue = true;
}
}
else {
$scope.users[i].estado= 'Available';
gotValue = true;
}
}
}
}
In AngularJS, there is no break for loops,etc., so one has to go with logic manually.
A similar case has been demonstrated here.
Here, I have created a variable f, which has been set to false initially. On forEach loop, based on a condition, it is made to true, further which it works as break.
Please find the code below:
HTML:
<div ng-app="app" ng-controller="test"></div>
JS:
var app = angular.module('app',[]);
app.controller ('test', function ($scope){
var f = false;
angular.forEach([1,2,3,4,5], function(v,k){
if(k > 2){
f = true;
}
if(!f) {
document.write('value = ' + v + ' <br>');
}
});
});

$scope.$watch callback executes after a delay

I have the following:
$scope.$watch('duration.dayPreference',function(value){
console.log(value);
if(value=='every')
{
that.duration.days = 1;
}
else if(value=='selected')
{
//alert('test');
that.duration.days=[];
}
else if(value=='everyday')
{
that.duration.days='everyday';
}
});
this.selectDay = function (day) {
$scope.duration.dayPreference = 'selected';
//$scope.$apply();
/*if(typeof(this.duration.days)!='object')
{
this.duration.days=[];
}*/
var index = this.duration.days.indexOf(day);
if (index == -1) {
//alert('test2');
this.duration.days.push(day);
}
else {
this.duration.days.splice(index, 1);
}
}
In this, when I do $scope.duration.dayPreference = 'selected'; I expect the line below it to have the this.duration.days set to a blank array. But it doesn't. Upon a closer inspection, I found that the callback in the $watch runs after the line below the assignment.
It may be very probable that, $watch may be using some kinda timers internally. What should be the way to do it then.
The watch won't be triggered until the digest is run. This will be after your entire function is compete.
If you consider that AngularJS is itself written in JavaScript, there would be no way for it to react to your setting of a property at the time. You are using the thread yourself. It can only wait for you to finish and then react.
As for what to do instead...
Perhaps you could call that watch function manually?
Or maybe the code which expects the empty array should belong inside the watch?
Watch will trigger on the $digest, which will occur after current cycle/code finishes running. You need to figure out a way of rearranging your code that handles things asynchronously. One possible quick solution might be:
var selectedDays = [];
$scope.$watch('duration.dayPreference',function(value){
console.log(value);
if(value=='every')
{
that.duration.days = 1;
}
else if(value=='selected')
{
//alert('test');
that.duration.days = selectedDays;
}
else if(value=='everyday')
{
that.duration.days='everyday';
}
});
this.selectDay = function (day) {
$scope.duration.dayPreference = 'selected';
var index = selectedDays.indexOf(day);
if (index == -1) {
//alert('test2');
selectedDays.push(day);
}
else {
selectedDays.splice(index, 1);
}
}

checkbox filter for json array in Angularjs

I have create a filter but this filter is not working with array inside array.
'http://plnkr.co/edit/oygy79j3xyoGJmiPHm4g?p=info'
Above plkr link is working demo.
app.filter('checkboxFilter', function($parse) {
var cache = { //create an cache in the closure
result: [],
checkboxData: {}
};
function prepareGroups(checkboxData) {
var groupedSelections = {};
Object.keys(checkboxData).forEach(function(prop) {
//console.log(prop);
if (!checkboxData[prop]) {
return;
} //no need to create a function
var ar = prop.split('=');
//console.log("ar is - "+ar);
if (ar[1] === 'true') {
ar[1] = true;
} //catch booleans
if (ar[1] === 'false') {
ar[1] = false;
} //catch booleans
/* replacing 0 with true for show all offers */
if(ar[0]=='SplOfferAvailable.text'){
ar[1]='true';
}else{
}
//make sure the selection is there!
groupedSelections[ar[0]] = groupedSelections[ar[0]] || [];
//at the value to the group.
groupedSelections[ar[0]].push(ar[1]);
});
return groupedSelections;
}
function prepareChecks(checkboxData) {
var groupedSelections = prepareGroups(checkboxData);
var checks = [];
//console.log(groupedSelections);
Object.keys(groupedSelections).forEach(function(group) {
//console.log("groupedSelections- "+groupedSelections);
//console.log("group- "+group);
var needToInclude = function(item) {
//console.log("item- "+item);
// use the angular parser to get the data for the comparson out.
var itemValue = $parse(group)(item);
var valueArr = groupedSelections[group];
//console.log("valueArr- "+valueArr);
function checkValue(value) { //helper function
return value == itemValue;
}
//check if one of the values is included.
return valueArr.some(checkValue);
};
checks.push(needToInclude); //store the function for later use
});
return checks;
}
return function(input, checkboxData, purgeCache) {
if (!purgeCache) { //can I return a previous 'run'?
// is the request the same as before, and is there an result already?
if (angular.equals(checkboxData, cache.checkboxData) && cache.result.length) {
return cache.result; //Done!
}
}
cache.checkboxData = angular.copy(checkboxData);
var result = []; // this holds the results
//prepare the checking functions just once.
var checks = prepareChecks(checkboxData);
input.every(function(item) {
if (checks.every(function(check) {
return check(item);
})) {
result.push(item);
}
return result.length < 10000000; //max out at 100 results!
});
cache.result = result; //store in chache
return result;
};
});
above code is for check box filter.
when i click on checkbox called "Availability" it does not filter the result.
Please help me out.
Thanks.
I think that the way you are navigating through json is wrong because if you put in this way it works
"Location": "Riyadh",
"AvlStatus": "AVAILABLE"
"Rooms": {.....
You have to go in some way through Rooms and right now I think you're not doing that

Resources