How to properly parse an array of Fetch responses
In trying to implement functionality to enable users to make partial updates to some data, I have come up with the following logical operations:
- Fetch and load data fields on a form.
- The user makes edits to some editable fields and hits save
- Check to see if fields have actually changed then map out fields to update
- Build an array of fetch promises (one for each editable field: the API endpoint for
PATCH
ing each editable field is distinct) - Using
Promise.all
, get an array of responses (promises) - Parse the array of responses to get data I am interested in.
The following is how I have actually implemented the above:
/* 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 }),
});
},
This works fine but for clarity's sake:
- Is this approach sound or is there a better way to implement the above?
- How can I combine the two distinct steps in the
editRecord
function?
javascript async-await es6-promise fetch-api
add a comment |
In trying to implement functionality to enable users to make partial updates to some data, I have come up with the following logical operations:
- Fetch and load data fields on a form.
- The user makes edits to some editable fields and hits save
- Check to see if fields have actually changed then map out fields to update
- Build an array of fetch promises (one for each editable field: the API endpoint for
PATCH
ing each editable field is distinct) - Using
Promise.all
, get an array of responses (promises) - Parse the array of responses to get data I am interested in.
The following is how I have actually implemented the above:
/* 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 }),
});
},
This works fine but for clarity's sake:
- Is this approach sound or is there a better way to implement the above?
- How can I combine the two distinct steps in the
editRecord
function?
javascript async-await es6-promise fetch-api
add a comment |
In trying to implement functionality to enable users to make partial updates to some data, I have come up with the following logical operations:
- Fetch and load data fields on a form.
- The user makes edits to some editable fields and hits save
- Check to see if fields have actually changed then map out fields to update
- Build an array of fetch promises (one for each editable field: the API endpoint for
PATCH
ing each editable field is distinct) - Using
Promise.all
, get an array of responses (promises) - Parse the array of responses to get data I am interested in.
The following is how I have actually implemented the above:
/* 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 }),
});
},
This works fine but for clarity's sake:
- Is this approach sound or is there a better way to implement the above?
- How can I combine the two distinct steps in the
editRecord
function?
javascript async-await es6-promise fetch-api
In trying to implement functionality to enable users to make partial updates to some data, I have come up with the following logical operations:
- Fetch and load data fields on a form.
- The user makes edits to some editable fields and hits save
- Check to see if fields have actually changed then map out fields to update
- Build an array of fetch promises (one for each editable field: the API endpoint for
PATCH
ing each editable field is distinct) - Using
Promise.all
, get an array of responses (promises) - Parse the array of responses to get data I am interested in.
The following is how I have actually implemented the above:
/* 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 }),
});
},
This works fine but for clarity's sake:
- Is this approach sound or is there a better way to implement the above?
- How can I combine the two distinct steps in the
editRecord
function?
javascript async-await es6-promise fetch-api
javascript async-await es6-promise fetch-api
edited Jan 1 at 8:15
Oguntoye
asked Dec 31 '18 at 19:07
OguntoyeOguntoye
10210
10210
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Looks good, if there were anything to move, it'd be the responsePromises.reduce
, up into the then
block, or have that one return the mapped responses into a new then
block.
/* 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);
});
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53990681%2fhow-to-properly-parse-an-array-of-fetch-responses%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Looks good, if there were anything to move, it'd be the responsePromises.reduce
, up into the then
block, or have that one return the mapped responses into a new then
block.
/* 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);
});
}
add a comment |
Looks good, if there were anything to move, it'd be the responsePromises.reduce
, up into the then
block, or have that one return the mapped responses into a new then
block.
/* 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);
});
}
add a comment |
Looks good, if there were anything to move, it'd be the responsePromises.reduce
, up into the then
block, or have that one return the mapped responses into a new then
block.
/* 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);
});
}
Looks good, if there were anything to move, it'd be the responsePromises.reduce
, up into the then
block, or have that one return the mapped responses into a new then
block.
/* 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);
});
}
/* 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);
});
}
/* 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);
});
}
answered Jan 1 at 8:35
Drew ReeseDrew Reese
950211
950211
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53990681%2fhow-to-properly-parse-an-array-of-fetch-responses%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown