5

Considering this example:

    if(this.plantService.plants[id])
    {
        if(this.plantService.plants[id].Name)
        {
            if(this.plantService.plants[id].Name[0])
                return this.plantService.plants[id].Name[0].value;
            else
                return '';
        }
        else
            return '';        
    }    
    return '';

I am wondering if it is possible to simplify what I am doing here.

My goal is to test the object-chain this.plantService.plants[id].Name[0] for validity.

However, if I just test if(this.plantService.plants[id].Name[0]) {...} exceptions are thrown.

Any proposals? :)

Liam
  • 27,717
  • 28
  • 128
  • 190
David
  • 1,275
  • 2
  • 17
  • 27
  • 2
    you could use the `&&` operator in your if like this: `if(this.plantService.plants[id] && this.plantService.plants[id].Name && this.plantService.plants[id].Name[0]){return this.plantService.plants[id].Name[0].value} else {return ''}` – Kevin Kloet Nov 22 '16 at 15:10
  • Please show us the exception thrown. you only say there is, but what is that? –  Nov 22 '16 at 15:10
  • 1
    @SuperCoolHandsomeGelBoy It would be a `TypeError`, as you'd be attempting to access a property on `undefined`. – Madara's Ghost Nov 22 '16 at 15:11
  • @SuperCoolHandsomeGelBoy accessing variable of `undefined` – Josué Zatarain Nov 22 '16 at 15:12
  • 2
    You could [catch the exception](http://www.w3schools.com/Js/js_errors.asp). – GolezTrol Nov 22 '16 at 15:12
  • Which bit exactly are you trying to test? The entire chain? So any of those objects could be `undefined`? – Liam Nov 22 '16 at 15:14
  • I was just going to say, you could do a try/catch, it'll either be undefined or the value so just have an exception when undefined is returned and instead return your empty character. I'd write it out but don't have the time at the moment – Mike Nov 22 '16 at 15:14

3 Answers3

4

You could reduce the array with the object, after checking value and type.

function getIn(object, keys, def)  {
    return keys.reduce(function (o, k) {
        return o && typeof o === 'object' && k in o ? o[k] : def;
    }, object);
}

var object = { plantService: { plants: [{ Name: [{ value: 42 }] }] } };

console.log(getIn(object, ['plantService', 'plants', 0, 'Name', 0, 'value'], 'default value'));
console.log(getIn(object, ['b', 'c', 'd', 'e'], 'default value'));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
2

You could write a simple function on your own like,

function getVal(obj, propQueue, defaultValue) {
  for (var prop of propQueue) {
    if ((obj = obj[prop]) === undefined) {
      break;
    }
  }

  return obj || defaultValue;
}

Now you can call it like,

var value = getVal(this, ["plantService", "plants", id, "name" 0], "");
console.log(value); //either "" or the real value.
Rajaprabhu Aravindasamy
  • 66,513
  • 17
  • 101
  • 130
0

You can try this:

if(this.plantService.plants[id] && this.plantService.plants[id].Name && this.plantService.plants[id].Name[0]){
        return this.plantService.plants[id].Name[0].value;

        }else{

    return '';
}

Or maybe your problem is that your model is not complete and you need to be sure of that in order to prevent these validations and replace with this:

return this.plantService.plants[id].Name[0].value;
Kevin Kloet
  • 1,086
  • 1
  • 11
  • 21