CookieThief
CookieThief

Reputation: 166

How to null check object property with a variable

data, roles and infos are variables that came from an API, Here I manually add array's index whereas in my code I loop the keys.

How to one line check if the attribute is null ?

Is there a way to access property like x?[roles[0]]?[infos[0]]

const data = [{player: {fname: 'player', lname: 'one'}, 
              { enemy: {lname: 'two'},
              {  ally: {fname: 'player'}]
const roles = ['player','ally']
const infos  = ['fname','lname']

data.map(x => {
    const firstPlayer  = `${x[roles[0]][infos[0]]} ${x[roles[0]][infos[1]]}`
    const secondPlayer = `${x[roles[1]][infos[0]]} ${x[roles[1]][infos[1]]}`
    return `hello ${firstPlayer} and ${secondPlayer}`
});

Upvotes: 0

Views: 350

Answers (2)

Doc
Doc

Reputation: 681

I would use a fallback value to cover undefined values like this:

const data = [
{
      player: {
        fname: 'player',
        lname: 'one'
      },
      
        enemy: {
          lname: 'two'
        },
        
          ally: {
            fname: 'player'
          }}];
        const roles = ['player', 'ally'];
        const infos = ['fname', 'lname'];

        const res = data.map((x) => {
          const firstPlayer = (x[roles[0]][infos[0]] || '') + ' ' + (x[roles[0]][infos[1]] || '')
          const secondPlayer = (x[roles[1]][infos[0]] || '') + ' ' + (x[roles[1]][infos[1]] || '')
          return ('hello ' + firstPlayer + ' and ' + secondPlayer).trim();
        });

        console.log(res);

By using (maybeUndefinedVar || 'fallbackValue') you can handle when the value is missing.

Note that this is valid only if you are sure your first property access is surely not undefined. In the opposite case, you should also apply the other anwser solution, and access properties in safety way like the following:

const data = [
{
      player: {
        fname: 'player',
        lname: 'one'
      },
      
        enemy: {
          lname: 'two'
        },
        
          allyNotExist: {
            fname: 'player'
          }}];
        const roles = ['player', 'ally'];
        const infos = ['fname', 'lname'];

        const res = data.map((x) => {
          const firstPlayer = (x?.[roles[0]]?.[infos[0]] || '') + ' ' + (x?.[roles[0]]?.[infos[1]] || '')
          const secondPlayer = (x?.[roles[1]]?.[infos[0]] || 'NoName') + ' ' + (x?.[roles[1]]?.[infos[1]] || 'NoSurname')
          return ('hello ' + firstPlayer + ' and ' + secondPlayer).trim();
        });

        console.log(res);

As you see, ally is no more present, and this way we are safe. If ally is not present in the first example, it fail for accessing properties of undefined.

P.s. Sorry if i changed from ` strings to ' strings concat, but this snippent doesn't allow ` syntax.

This should be

const firstPlayer  = `${(x?.[roles[0]]?.[infos[0]] || '')} ${(x?.[roles[0]]?.[infos[1]] || '')}`

Upvotes: 1

Radu Diță
Radu Diță

Reputation: 14171

You can use optional chaining, this works on array indexes also.

const firstPlayer  = `${x?.[roles[0]]?.[infos[0]]} ${x?.[roles[0]]?.[infos[1]]}`

Just note that you'll get undefined inside the string if the chain is broken.

Upvotes: 1

Related Questions