A space to discuss GraphQL queries, mutations, troubleshooting, throttling, and best practices.
When I've created files I want to save links. But if I request files immediately, I don't have urls in the response. But if I use setTimeut, I get them!!!!!
There's the code:
const createFiles = async (files, stagedTargets, graphql) => {
const response = await graphql(`
mutation fileCreate($files: [FileCreateInput!]!) {
fileCreate(files: $files) {
files {
fileErrors {
code
details
message
}
... on MediaImage {
id
}
... on GenericFile {
id
}
... on Video {
id
}
}
userErrors {
field
message
}
}
}
`, {
variables: {
files: prepareFilesToCreate(stagedTargets, files),
}
});
const result = await response.json();
return {
response: result,
errors: result.data.fileCreate.userErrors,
}
}
const getFilesByIds = async (files, graphql) => {
try {
const response = await graphql(`
query ($ids: [ID!]!) {
nodes(ids: $ids) {
__typename
... on GenericFile {
id
url
fileErrors {
code
details
message
}
}
... on MediaImage {
id
fileErrors {
code
details
message
}
image {
url
}
}
}
}
`, {
variables: {
ids: files.map((file) => file.id),
}
});
const result = await response.json();
return {
response: result.data.nodes,
errors: result.errors,
}
} catch (e) {
return {
errors: [e?.message || 'Files getting error']
}
}
}
it doesn't work:
const newFiles = await getFilesByIds(createFilesResponse.data.fileCreate.files, graphql);
console.log('newFiles', newFiles.response);
console.log('newFiles2', newFiles.response.map((file) => file.image));
console.log('errors', newFiles.errors);
But it works:
setTimeout(async () => {
const newFiles = await getFilesByIds(createFilesResponse.data.fileCreate.files, graphql);
console.log('newFiles', newFiles.response);
console.log('newFiles2', newFiles.response.map((file) => file.image));
console.log('errors', newFiles.errors);
}, 5000)
I guess createdFiles shoud set links before request, not after....
Solved! Go to the solution
This is an accepted solution.
HI EvilGranny,
Your observation is correct. The file creation process is asynchronous, meaning that the file might not be immediately available after the createFiles
function is called. This is why when you immediately call getFilesByIds
, the URLs are not available yet. However, when you delay the execution of getFilesByIds
by using setTimeout
, the files have enough time to be processed and their URLs become available.
A common way to handle this is to use some kind of polling mechanism:
Hope this helps,
Liam | Developer Advocate @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
And i'm using second request because fileCreate returns nothing
This is an accepted solution.
HI EvilGranny,
Your observation is correct. The file creation process is asynchronous, meaning that the file might not be immediately available after the createFiles
function is called. This is why when you immediately call getFilesByIds
, the URLs are not available yet. However, when you delay the execution of getFilesByIds
by using setTimeout
, the files have enough time to be processed and their URLs become available.
A common way to handle this is to use some kind of polling mechanism:
Hope this helps,
Liam | Developer Advocate @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
Yeah... It helps, thank you, but that's looks like very big issue. First of all it shouldn't work this way and it wasn't described in the docs...
I believe, waiting process should be on your side