React Невозможно прочитать свойство 'lastName' из неопределенного - PullRequest
0 голосов
/ 18 февраля 2020

Я пытаюсь объединить данные двух API в новом API, но получаю ошибку Uncaught TypeError: Cannot read property 'lastName' of undefined. Это происходит потому, что не находит lastName, когда он отсутствует в API2. В этом случае я хочу инициализировать ее как пустую строку, если не удается найти ее в объединенном API.

API 1 look:

data: {
0: {
id: 1234
company: 'String',
name: 'Test'
}
1: {
id: 2345
company: 'String1',
name: 'Test 1'
}
2: {
id: 3456
company: 'String2',
name: 'Test 2'
}
3: {
id: 4567
company: 'String3',
name: 'Test 3'
}
}

API2 look:

data: {
0: {
id: 1234
company: 'String',
name: 'Test'
lastName: 'Second'
}
1: {
id: 2345
company: 'String1',
name: 'Test 1'
}
2: {
id: 3456
company: 'String2',
name: 'Test 2'
lastName: 'Second 1'
 }
3: {
id: 4567
company: 'String3',
name: 'Test 3'
lastName: 'Second 3'
}
}

Внешний вид объединенного API:

data: {
0: {
id: 1234
company: 'String',
name: 'Test'
lastName: 'Second Test' //lastName from API 2 + name from API 1
}
1: {
id: 2345
company: 'String1',
name: 'Test 1'
lastName: '' //lastName from API 2 + name from API 1
}
2: {
id: 3456
company: 'String2',
name: 'Test 2'
lastName: 'Second 1 Test 2' //lastName from API 2 + name from API 1
}
3: {
id: 4567
company: 'String3',
name: 'Test 3'
lastName: 'Second 3 Test 3' //lastName from API 2 + name from API 1
}

Полученные данные:

const [api1, setApi1] = useState([]);
const [api2, setApi2] = useState([]);
const [mergeApi, setMergeAPi] = useState([]);

useEffect(() => {
  fetch('api1')
  .then((response) => {
    setApi1(response);
  });
});

useEffect(() => {
  fetch('api2')
  .then((response) => {
    setApi2(response);
  });
});

useEffect(() => {
  const data = api1.map(getData => {
    const d = api2.find((object) => {
      // return  object.name === api1.name;
      return  object.name === getData.name; 
    });
    return {
      ...api1,
      // name: `${d.name} - ${d.lastName}` 
      name: d ? `${d.name} - ${d.lastName}` : ""; // solution there
    }
  });
});

Ответы [ 5 ]

2 голосов
/ 18 февраля 2020

Вы можете использовать встроенный оператор ||:

${d.lastName || ""}

Также вам необходимо изменить объект здесь:

return  object.name === getData.name; //<----change here.
0 голосов
/ 18 февраля 2020

Я нашел решение для этого:

useEffect(() => {
  const data = api1.map(getData => {
    const d = api2.find((object) => {
      // return  object.name === api1.name;
      return  object.name === getData.name; 
    });
    return {
      ...api1,
      // name: `${d.name} - ${d.lastName}` 
      name: d ? `${d.name} - ${d.lastName}` : ""; // solution there
    }
  });
});
0 голосов
/ 18 февраля 2020

Попробуйте что-нибудь подобное. 1) данные api1 и api2 выглядят как объекты, имеют Object.values для получения массива значений.
2) Изменить, чтобы найти функцию. Проверка obj2.name === obj1.name
3) проверьте значение d перед использованием.

const api1 = {
  0: {
    id: 1234,
    company: "String",
    name: "Test"
  },
  1: {
    id: 2345,
    company: "String1",
    name: "Test 1"
  },
  2: {
    id: 3456,
    company: "String2",
    name: "Test 2"
  },
  3: {
    id: 4567,
    company: "String3",
    name: "Test 3"
  }
};

const api2 = {
  0: {
    id: 1234,
    company: "String",
    name: "Test",
    lastName: "Second"
  },
  1: {
    id: 2345,
    company: "String1",
    name: "Test 1"
  },
  2: {
    id: 3456,
    company: "String2",
    name: "Test 2",
    lastName: "Second 1"
  },
  3: {
    id: 4567,
    company: "String3",
    name: "Test 3",
    lastName: "Second 3"
  }
};

const data = Object.values(api1).map(obj1 => {
  const d = Object.values(api2).find(obj2 => obj2.name === obj1.name);
  return {
    ...obj1,
    name: d ? `${d.name} - ${d.lastName}` : obj1
  };
});

console.log(data);
0 голосов
/ 18 февраля 2020

Попробуйте сделать это. Может быть случай, когда в ваших реальных данных может быть какое-то имя, которого нет в api2.

const data = api1.map(getData => {
  const d = api2.find((object) => {
    return  object.name === getData.name; // <---- NOTE THIS
  });

  if (!d) { // <---- NOTE THIS
    return getData 
  }

  return {
    ...getData, // <---- NOTE THIS
    name: `${d.name} - ${d.lastName}`
  }
});

idk, если у вас действительно есть id в объектах, но я бы сравнил по id, а не по имени.

return  object.id === getData.id;
0 голосов
/ 18 февраля 2020
useEffect(() => {
  const data = api1.map(getData => {
    const d = api2.find((object) => {
      // return  object.name === api1.name;
      return  object.name === getData.name; //replaced but doesn't work
    });
    return {
      ...api1,
      name: `${d.name} - ${d.lastName}`
    }
  });
});

Array.find возвращает undefined, если в массиве нет соответствующих элементов. так что d может быть undefind, и, следовательно, выдает ошибку кода. В d.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

useEffect(() => {
  const data = api1.map(getData => {
    ...
    if (d) {
      return {
        ...getData,
        name: `${d.name} - ${d.lastName}` 
      }
    } else {
      // some code to handle if d is undefined
    }
  });
});
отсутствует свойство 'фамилия'.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...