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]] || '')}`