1

I have a function in my angular factory service to fetch some data. How do I check that a certain value exists inside the object before using it?

here is what I've been trying...

categories.fetch = function(app){
  if(!app.subject.name.length){
    return false;
  }
  var p = Restangular.all('v1/categories').getList({app.subject.name.toUpperCase()});
}

so I just want to check that there is value in app.subject.name before using it in the restanguar call...

Thanks

4 Answers 4

2

Your code will retrieve the value of the length property and attempt to convert it to a Boolean for the purposes of the if/then test, but this will throw an error if the value happens to be null.

Also, if your test is simply: app.subject.name, you will get a false positive if the value happens to be a falsy value, like 0 or false, which are both perfectly valid values.

With strings, the simplest test is to check for a non-empty string and non-null. If the value was provided by an end-user, it's a good idea to call .trim() on the string first to remove any leading or trailing spaces that may have been inadvertently added.

var myObj = { 
  test : 0,
  testing : null
}


// This will fail with an error when the value is null
/*
if(myObj.testing.length){ 
  console.log("The testing property has a value."); 
} else {
  console.log("The testing property doesn't have a value."); 
}
*/

// This will return a false positive when the value is falsy
if(myObj.test){ 
  console.log("The test property has a value."); 
} else {
  console.log("The test property doesn't have a value."); // <-- Incorretly reports this
}

// This explicit test will pass and fail correctly
if(myObj.testing !== "" && myObj.testing !== null){ 
  console.log("The testing property has a value."); 
} else {
  console.log("The testing property doesn't have a value."); 
}

Also, if the value is there, put your code in the ifs true branch and don't worry about return false.

categories.fetch = function(app){
  if(app.subject.name !== "" && app.subject.name !== null) {
    var p = 
      Restangular.all('v1/categories').getList({app.subject.name.toUpperCase()});
  }
Sign up to request clarification or add additional context in comments.

4 Comments

But a length property of 0 is falsy, so !object.length is just a shortcode for checking whether it's >0
This will also throw an undefined TypeError in the case that name doesn't exist on app.subject at all.
Of course it will. That will happen anytime you check a property that doesn't exist. That's like saying that sdlfj = 894#$@$%$.[]{}{ will throw a syntax error.
@Connum Since there is a possibility that the property could be null, length shouldn't be used at all, since it will throw an error in that case.
1

The hasOwnProperty() method returns a boolean indicating whether the object has the specified property. MDN Docs

Example

var priceOfFood = {
    pizza: 14,
    burger 10
}

priceOfFood.hasOwnProperty('pizza') // true
priceOfFood['pizza'] // 14
priceOfFood.hasOwnProperty('chips') // false
priceOfFood['chips'] // undefined

3 Comments

How does this help to check if a property has a value. The question wasn't how to check if a property exists.
This is an explanation by analogy. I think that OP is asking not about checking a value but a key.
The OP quite clearly says: "so i just want to check that there is value in app.subject.name before using it in the restanguar call"
1

I know the question does not ask about Lodash, but I manage to do this kind of checking a lot with it and it works flawlessly. In your case it would be something like this:

categories.fetch = function(app){
  if (_.isEmpty(app.subject.name)) {
   return false;
  }
 var p = Restangular.all('v1/categories').getList({app.subject.name.toUpperCase()});
}

If you expect that keys may not be available inside app object you can do it like this:

categories.fetch = function(app){
  if (_.isEmpty(_.get(app, "subject.name"))) {
   return false;
  }
 var p = Restangular.all('v1/categories').getList({app.subject.name.toUpperCase()});
}

Or simply:

categories.fetch = function(app){
  if (!_.get(app, "subject.name")) {
   return false;
  }
 var p = Restangular.all('v1/categories').getList({app.subject.name.toUpperCase()});
}

5 Comments

What if app.subject.name === ""?
I don't see any problem there, could you recheck it _.isEmpty(data.career.field) return true as it should be.
it does return true, but it shouldn't if the value is an empty string.
Ah sorry, I just forgot to remove negation from the answer, I have corrected it.
So the problem was with the original answer, otherwise _.isEmpty is working as expected.
0

Simple as that:

if(!app.subject.name){
        return ;
    }

6 Comments

As I've noted on several of the other answers, this will throw a false positive if the value is a falsy value like 0 or false, which are both valid values.
It won't get in the if statement since the input value is a string because the expression '0' or 'false' are true in an if statement
That depends on how the test is written. if("0" == true){} results in false, whereas if("0"){} results in true.
That's why I made the if statement look like this.
I understand, but generally, when there is one technique that can be ambiguous and potentially lead to errors and another that isn't and doesn't, the latter is advised. Testing for the existence of a string value is best done with !== "" && !== null after a .trim() call.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.