What does 'if(newcontact.id == null)' mean? - angularjs

I am new to programming and am trying to learn angularJS to build a web app. I came across an example contacts manager app and am having difficulty understanding part of it, namely the part that checks if a contact exists or not:
if($scope.newcontact.id == null)
Ok, I get that this checks if this is a new contact, but I don't understand what is happening in logical terms. I read up on null and understand it to mean that the thing being evaluated is known to exist, but does not have value.
So does this mean 'newcontact.id exists but does not have a value'?
Below is the javascript part of the app:
var uid = 1;
function ContactController($scope) {
$scope.contacts = [
{ id:0, 'name': 'Viral',
'email':'hello#gmail.com',
'phone': '123-2343-44'
}
];
$scope.saveContact = function() {
if($scope.newcontact.id == null) {
//if this is new contact, add it in contacts array
$scope.newcontact.id = uid++;
$scope.contacts.push($scope.newcontact);
} else {
//for existing contact, find this contact using id
//and update it.
for(i in $scope.contacts) {
if($scope.contacts[i].id == $scope.newcontact.id) {
$scope.contacts[i] = $scope.newcontact;
}
}
}
//clear the add contact form
$scope.newcontact = {};
}
$scope.delete = function(id) {
//search contact with given id and delete it
for(i in $scope.contacts) {
if($scope.contacts[i].id == id) {
$scope.contacts.splice(i,1);
$scope.newcontact = {};
}
}
}
$scope.edit = function(id) {
//search contact with given id and update it
for(i in $scope.contacts) {
if($scope.contacts[i].id == id) {
//we use angular.copy() method to create
//copy of original object
$scope.newcontact = angular.copy($scope.contacts[i]);
}
}
}
}

if ($scope.newcontact.id == null)
if $scope exists AND $scope has a property called newcontact which also exists AND newcontact has a property called id AND id has not been assigned a value.
By that statement the author assumes (or has previously checked) that $scope exists and is not null and that $scope.newcontact exists and is not null. The explicit check is that id is a property on newcontact that has not been assigned a value.

Related

localStorage Array Objects - How to check is Object Key Value exists

How would i check to see if the ID exists within the localStorage object key array
i am currenty using this and it does not work
if (favorites.includes(theid)) { alert('You Allready Added this Listing'); }
Also how do i pull the indivdual object array apart into ID , image , title
to make varibles
Thank you
Below is the Full Code
function checkfave (theid) {
// get favorites from local storage or empty array
var favorites = JSON.parse(localStorage.getItem('favorites')) || [];
var theimage = $('#theimage'+theid).attr('src');
var thetitle = $('#thetitle'+theid).text();
if (localStorage.getItem('favorites') != null) {
if (favorites.includes(theid)) { alert('You Allready Added this Listing'); }
}
favorites.push({ID:theid,IMAGE:theimage,TITLE:thetitle});
localStorage.setItem('favorites', JSON.stringify(favorites));
alert('You Just Added Listing '+theid+' To Your Favorites');
//Loop through the Favorites List and display in console (HIDDEN)
console.clear();
for (let i = 0; i < favorites.length; i++) {
console.log('ID= '+favorites[i].ID+' IMAGE='+favorites[i].IMAGE+' TITLE='+favorites[i].TITLE);
}//for loop
}
When you parse json using JSON.parse, a javascript object is created. You can access keys in javascript objects by simply using the bracket notation:
object[key] = value
If a key is not defined in an object, when you request the key you will get undefined. undefined is equivalent to false when evaluating an if clause so you can simply use
if (favorites[theid]) { alert('You Allready Added this Listing'); }
I found a solution after the suggestions
My solution was to check within a for loop using favorites[i].ID == theid
The final code is below. i am very sure it could be done another way, But this works for now.
function checkfave (theid) {
var favorites = JSON.parse(localStorage.getItem('favorites')) || [];
var theimage = $('#theimage'+theid).attr('src');
var thetitle = $('#thetitle'+theid).text();
var added=true;
//Loop through the Favorites List and display in console (HIDDEN)
for (let i = 0; i < favorites.length; i++) {
if ( favorites[i].ID == theid ) { alert('You allready Added Listing '+theid+' To Your Favorites'); var added=false; break; } else {var added=true;}
}//for loop
if (added===true) {
favorites.push({ID:theid,IMAGE:theimage,TITLE:thetitle});
localStorage.setItem('favorites', JSON.stringify(favorites));
alert('You Just Added Listing '+theid+' To Your Favorites');
}
}

Firebase .once(): Use success and failure callbacks

I have the following function in my Angular-app
$scope.retrieveProjectData = function() {
$scope.projectNumberNoChange = false;
// Only retrieve Data if the ProjectNumber changed
if (currentlySelectedProjectNumber != $scope.feedback.projectNumber.content) {
currentlySelectedProjectNumber = $scope.feedback.projectNumber.content;
// Go to database-reference based on the projectNumber
var projectsRef = firebaseDatabaseRef.child("projects");
var currentChild = projectsRef.child(currentlySelectedProjectNumber);
// retrieve data once and fill $scope.feedback
currentChild.once("value",
// If the project is found
function (dataSnapshot) {
// Fill selectedProject and hand over to writeDataFromSelectedProject()
var selectedProject = dataSnapshot.val();
// Fill $scope.feedback
writeDataFromSelectedProject(selectedProject);
},
// If no data is found
function () {
console.log("No data found");
});
}
// If the projectNumber didn't change, the projectNumberNoChangeMessage will be shown
else {
$scope.projectNumberNoChange = true;
}
};
The user has the possibility to load some data regarding his project-number (for instance: Name, email, tel) to make it faster for the user to fill a form.
In the part:
currentChild.once("value",
// If the project is found
function (dataSnapshot) {
// Fill selectedProject and hand over to writeDataFromSelectedProject()
var selectedProject = dataSnapshot.val();
// Fill $scope.feedback
writeDataFromSelectedProject(selectedProject);
},
// If no data is found
function () {
console.log("No data found");
});
only the first Callback-function is called, even if the projectNumber was not found. How can I use the "failureCallbackOrContext" as described in the docs?
Thanks for taking the time!
The problem was solved. I just checked the dataSnapshot.val() for beeing an object or null!

Angularjs filter multi level object

I need to create a filter in angularjs
My data looks something like this:
[{
name: 'account1',
accounts: [
{
name: 'account2',
accounts: []
},
{
name: 'account3',
accounts: [
{
name: 'account4',
accounts: []
}
]
}
]
}]
I need the filter return the full object if I use account4 for the search text. Or just the first 2 levels if I use account2 etc.
I have searched all over but cant find anything like this and have no idea where to start.
You'll need to create a custom filter to do what you're requesting. A controller filter will only allow you to provide an expression to include or exclude an ng-repeat item.
A custom filter will allow you to modify the model dynamically. You can splice the json object accordingly.
I'll provide an example when I'm back in in front of a pc.
I got it figured out finally. Here is the custom filter I created in case anyone else finds it useful:
.filter('accountsFilter', function() {
return function(items, searchStr) {
function filterAccounts(account, str) {
//if account name matches
if (account.name && account.name.toLowerCase().indexOf(str.toLowerCase()) > -1) {
//expand parent account
if (account.accounts && account.accounts.length > 0) account.expand = true;
//return account
return account;
} else
//account name doesnt match. check sub accounts
if (account.accounts && account.accounts.length > 0) {
//has accounts
var fa = [];
angular.forEach(account.accounts, function(act, k) {
var a = filterAccounts(act, str);
//if account was returned
if (a !== false) {
//add account to filtered accounts
fa.push(act);
}
});
//add accounts to parent account
account.accounts = fa;
//if there are sub-accounts
if (fa.length > 0) {
//make sure account is expanded to show sub accounts
if (account.accounts && account.accounts.length > 0) account.expand = true;
//return account
return account;
//no sub accounts left
} else {
//check and return if main account matches
return filterAccounts(account, str);
}
//no matches
} else {
return false;
}
}
//copy accounts list to prevent original being altered
var accounts = angular.copy(items);
var filtered = [];
//loop through accounts list
angular.forEach(accounts, function(account) {
//check if current account matches
var a = filterAccounts(account, searchStr.name);
if (a) {
//add to filtered list
filtered.push(a);
}
});
return filtered;
};
})

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

Nodejs async data duplication

I'm having some problems with one async process on nodejs.
I'm getting some data from a remote JSON and adding it in my array, this JSON have some duplicated values, and I need check if it already exists on my array before add it to avoid data duplication.
My problem is when I start the loop between the JSON values, the loop call the next value before the latest one be process be finished, so, my array is filled with duplicated data instead of maintain only one item per type.
Look my current code:
BookRegistration.prototype.process_new_books_list = function(data, callback) {
var i = 0,
self = this;
_.each(data, function(book) {
i++;
console.log('\n\n ------------------------------------------------------------ \n\n');
console.log('BOOK: ' + book.volumeInfo.title);
self.process_author(book, function() { console.log('in author'); });
console.log('\n\n ------------------------------------------------------------');
if(i == data.length) callback();
})
}
BookRegistration.prototype.process_author = function(book, callback) {
if(book.volumeInfo.authors) {
var author = { name: book.volumeInfo.authors[0].toLowerCase() };
if(!this.in_array(this.authors, author)) {
this.authors.push(author);
callback();
}
}
}
BookRegistration.prototype.in_array = function(list, obj) {
for(i in list) { if(list[i] === obj) return true; }
return false;
}
The result is:
[{name: author1 }, {name: author2}, {name: author1}]
And I need:
[{name: author1 }, {name: author2}]
UPDATED:
The solution suggested by #Zub works fine with arrays, but not with sequelize and mysql database.
When I try to save my authors list on the database, the data is duplicated, because the system started to save another array element before finish to save the last one.
What is the correct pattern on this case?
My code using database is:
BookRegistration.prototype.process_author = function(book, callback) {
if(book.volumeInfo.authors) {
var author = { name: book.volumeInfo.authors[0].toLowerCase() };
var self = this;
models.Author.count({ where: { name: book.volumeInfo.authors[0].toLowerCase() }}).success(function(count) {
if(count < 1) {
models.Author.create(author).success(function(author) {
console.log('SALVANDO AUTHOR');
self.process_publisher({ book:book, author:author }, callback);
});
} else {
models.Author.find({where: { name: book.volumeInfo.authors[0].toLowerCase() }}).success(function(author) {
console.log('FIND AUTHOR');
self.process_publisher({ book:book, author:author }, callback);
});
}
});
// if(!this.in_array(this.authors, 'name', author)) {
// this.authors.push(author);
// console.log('AQUI NO AUTHOR');
// this.process_publisher(book, callback);
// }
}
}
How can I avoid data duplication in an async process?
This is because you are comparing different objects and result is always false.
Just for experiment type in the console:
var obj1 = {a:1};
var obj2 = {a:1};
obj1 == obj2; //false
When comparing objects (as well as arrays) it only results true when obj1 links to obj2:
var obj1 = {a:1};
var obj2 = obj1;
obj1 == obj2; //true
Since you create new author objects in each process_author call you always get false when comparing.
In your case the solution would be to compare name property for each book:
BookRegistration.prototype.in_array = function(list, obj) {
for(i in list) { if(list[i].name === obj.name) return true; }
return false;
}
EDIT (related to your comment question):
I would rewrite process_new_books_list method as follows:
BookRegistration.prototype.process_new_books_list = function(data, callback) {
var i = 0,
self = this;
(function nextBook() {
var book = data[i];
if (!book) {
callback();
return;
}
self.process_author(book, function() {
i++;
nextBook();
});
})();
}
In this case next process_author is being called not immediately (like with _.each), but after callback is executed, so you have consequence in your program.
Not sure is this works though.
Sorry for my English, I'm not a native English speaker

Resources