Как правильно разобрать массив ответов Fetch - PullRequest
0 голосов
/ 31 декабря 2018

Пытаясь реализовать функциональность, позволяющую пользователям выполнять частичное обновление некоторых данных, я предложил следующие логические операции:

  1. Извлечение и загрузка полей данных в форме.
  2. Пользователь вносит изменения в некоторые редактируемые поля и нажимает кнопку save.
  3. Проверьте, действительно ли поля изменились, затем отобразите поля для обновления
  4. Создайте массив обещаний выборки (по одному для каждогоредактируемое поле: конечная точка API для PATCH отличается от каждого редактируемого поля)
  5. Используя Promise.all, получить массив ответов (обещаний)
  6. Анализировать массив ответов для получения данныхМеня интересует.

Вот как я на самом деле реализовал вышеупомянутое:

 /*   EDIT RECORD
  * @param path: path to the record (ex: '/record/2')
  * @param fields: object containing fields to update (ex: { comment: "new comment here" })
  */
   async editRecord(path, fields) {
     const responsePromises = await Promise.all(
       Object.keys(fields).map(field =>                 // create an array of a number of fetch requests detemined by number of fields
         this.patchRecord(path, field, fields[field])      // returns a fetch request
       )
     ).then(res => res.map(each => each.json()));       // return  an array of "json decoded"?? response promises  


  /*
   * For each response promise:
   *  1. Grab a message or an errorlist
   *  2. Append the message, or list of errors to an object holding the errors/messages of already parsed responses
   */
    const { errors, messages } = await responsePromises.reduce(
      async (parsedObjectPromise, response) => {
        const parsedObject = await parsedObjectPromise;
        const { data, errors: responseErrors } = await response;
        let message;

        if (data) [message] = data;

        if (responseErrors) parsedObject.errors.push(...responseErrors);
        if (message) parsedObject.messages.push(message);

        return parsedObject;
      },
      { errors: [], messages: [] }
    );

    console.log(errors, messages);
  },




  /*
   *  Returns a fetch request for one datafield update
   * @param path: path to the record (ex: '/record/2')
   * @param field: field to update (ex: 'comment')
   * @param value: value to update field with  (ex: 'new comment')
   */   

  patchRecord(path, field, value) {
    let requestUrl = IR_HELPERS.buildFetchPath({ singleRecordPath: path });
    requestUrl += `/${field}`;   // ex: 127.0.0.1:2343/record/2/comment

    return fetch(requestUrl, {
      method: 'PATCH',
      headers: {
        Accept: 'application/json',
        Authorization: `Bearer ${IR_HELPERS.token}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ [field]: value }),
    });
  },

Это прекрасно работает, но для ясности:

  1. Оправдан ли этот подход или есть лучший способ реализовать вышеизложенное?
  2. Как я могу объединить два разных шага в функции editRecord?

1 Ответ

0 голосов
/ 01 января 2019

Выглядит хорошо, если бы было что-то для перемещения, это был бы responsePromises.reduce, вверх в блок then или тот, который вернул бы отображенные ответы в новый then блок.

/*   EDIT RECORD
  * @param path: path to the record (ex: '/record/2')
  * @param fields: object containing fields to update (ex: { comment: "new comment here" })
  */
async editRecord(path, fields) {
  Promise.all(
    Object.keys(fields).map(field => 
      this.patchRecord(path, field, fields[field]))
  )
  .then(res => res.map(each => each.json()))
    /*
     * For each response promise:
     *  1. Grab a message or an errorlist
     *  2. Append the message, or list of errors to an object holding the errors/messages of already parsed responses
     */
  .then(responsePromises => responsePromises.reduce(
    async (parsedObjectPromise, response) => {
      const parsedObject = await parsedObjectPromise;
      const { data, errors: responseErrors } = await response;
      let message;

      if (data) [message] = data;

      if (responseErrors) parsedObject.errors.push(...responseErrors);
      if (message) parsedObject.messages.push(message);

      return parsedObject;
    },
    { errors: [], messages: [] }
  ))
  .then(({ errors, messages }) => {
    console.log(errors, messages);
  });       
}
...