При работе с внешним API могут возникнуть ситуации, когда вы захотите изменить значения или добавить новые ключи к объекту. Один из способов сделать это — создать внутренний API, содержащий объекты, получившие изменения. Вот полная разбивка и объяснение того, как это сделать! В качестве примера я буду создавать систему добавления лайков к постам, полученным из внешнего API.
Начнем с запроса GET от внешнего API:
function getExternalData(externalUrl){
return fetch(externalUrl, {
headers: {
Accept: 'application/json'
}
})
.then(response => response.json());
}
Затем мы хотим также создать запрос GET с нашим внутренним сервером:
function getInternalData(internalUrl){
return fetch(internalUrl)
.then(response => response.json());
}
Пока мы здесь, мы можем написать наши функции POST и PATCH:
function postNewData(newData){
fetch(internalUrl, {
method: "POST",
headers: {
"content-type" : "application/json"
},
body: JSON.stringify(newData)
}
}
function patchData(existingData){
fetch(`${internalUrl}/${existingData.id}`, {
method: "PATCH",
headers: {
"content=type" : "application/json"
},
body: JSON.stringify(existingData)
}
}
Затем мы можем написать функцию, добавляющую лайк к внешним данным API. Мы создадим кнопку и добавим к ней прослушиватель событий. При срабатывании запускается внутренняя функция API GET, а остальная часть функции выполняется в .then() после. Во-первых, выполняется проверка, чтобы увидеть, существуют ли данные уже внутри. Либо array.some, либо array.find будут искать во внутреннем API ключ, соответствующий ключу (предпочтительно идентификатору, который всегда будет уникальным) во внешнем объекте данных. array.some немедленно вернет значение true или false, для array.find потребуется !! поскольку он просто возвращает совпадающее значение, которое было бы истинным и неопределенным, ложным, если совпадения нет:
const dataExists = !!data.find(fetchedObj => fetchedObj.id === fetchData.id); //OR const dataExists = data.some(fetchedObj => fetchedObj.id === fetchData.id);
Если объект уже существует, то мы просто хотим внести наше изменение и исправить его. Мы можем использовать array.forEach с другим оператором if, который ищет совпадающие идентификаторы, чтобы быстро найти правильный объект, и вставить желаемое изменение, а затем запустить наш Функция ПАТЧ.
if(dataExists){
data.forEach(existingObject => {
if(existingObject.id === fetchData.id) {
existingObject.likes++;
patchData(existingData);
}
}
}
Если объект не существует, мы создадим новый объект, содержащий все те же необходимые ключи и значения, что и внешний объект, добавив наши новые ключи и значения по своему усмотрению. После этого мы можем просто запустить нашу функцию POST для нашего нового объекта.
else{
const newData = {
key: fetchData.key,
id: fetchData.id,
likes: 1
};
postNewData(newData);
}
При этом у нас будет кнопка, которая при нажатии будет проверять существующее совпадение, изменять и исправлять, если есть совпадение, и создавать и публиковать, если нет:
function addLikes(fetchData){
const likeButton = document.createElement('button');
likeButton.addEventListener('click', function(){
getInternalData().then(data => {
const dataExists = !!data.find(fetchedObj => fetchedObj.id === fetchData.id);
if(dataExists){
data.forEach(existingObject => {
if(existingObject.id === fetchData.id) {
existingObject.likes++;
patchData(existingData);
}
}
}
else{
const newData = {
key: fetchData.key,
id: fetchData.id,
likes: 1
};
postNewData(newData);
}
})
})
siteElement.append(likeButton);
}
Отсюда мы можем просто запустить внешнюю функцию выборки с нашей функцией прослушивания событий:
function finalResult(externalUrl){
getExternalData(externalUrl).then(data => addLikes(data));
}
finalResult(url);
И это все! Теперь у нас есть способ сохранить только те данные, которые нам нужны, и изменить их по своему усмотрению. Используя array.find() и array.some(), мы смогли проверить, были ли уже изменены данные, и при необходимости создать копию.