question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Upload of two and more scalars

See original GitHub issue

Hi! Thanks for repository.

I’m having a problem with uploading of two scalars.

My input with two scalars for mutation is:

input createTrainingInput {
  name: String!
  level: TrainingLevel!
  introduction: String!
  workoutDuration: String!
  description: String!
  goals: [String]!
  requirements: [String]!
  overallDuration: Int!
  intensity: Int!
  price: Int!
  promotionalVideo: Upload!
  coverPhoto: Upload!
}

When I upload small plain text files, everything is ok.

But when I’m trying to upload video one of the promises is in ‘pending’ state for a long time, until FileStreamDisconnectUploadError is thrown.

Resolvers code:

const { coverPhoto, promotionalVideo, ...properties } = input;

const [
    { stream: coverPhotoStream, filename: coverPhotoFilename },
    { stream: promotionalVideoStream, filename: promotionalVideoFilename },
] = await Promise.all([
    coverPhoto,
    promotionalVideo
]);

Version of apollo-upload-server is 5.0.0.

Please, advice what can be done in this situation.

Thank you.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:13 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
hkjeffchancommented, Apr 19, 2018

Do NOT do this, this will block the stream and will raise error.

    const { stream: coverPhotoStream, filename: coverPhotoFilename } = await coverPhoto;
    const { stream: promotionalVideoStream, filename: promotionalVideoFilename } = await promotionalVideo;

Wrap the stream operation in promise one by one, await all and then execute the rest operation. It should be something like this. I haven’t tested it but hopefully you get the idea.

createTraining: async (root, { input }, context) => {
    const { user } = context;
    const coach = await Coach.findOne({ user });
    const { coverPhoto, promotionalVideo, ...properties } = input;

    await Promise.all(
         new Promise( (resolve, reject) => {
              const { stream: coverPhotoStream, filename: coverPhotoFilename } = await coverPhoto;
              const photoFilename = getUploadPath('training_videos', coverPhotoFilename);
              await storage.save({
                      stream: coverPhotoStream,
                      filename: photoFilename
              });
              resolve(true);
         }),
         new Promise( (resolve, reject) => {
             const { stream: promotionalVideoStream, filename: promotionalVideoFilename } = await promotionalVideo;
             const videoFilename = getUploadPath('training_cover', promotionalVideoFilename);
             await storage.save({
                   stream: promotionalVideoStream,
                   filename: videoFilename
             });
             resolve(true);
         })
    );

    const training = new Training({
        coach,
        coverPhoto: coverPhotoFilename,
        promotionalVideo: videoFilename,
        ...properties
    });
    await training.save();
    return { training };
}
1reaction
hkjeffchancommented, Apr 17, 2018

After hours of research, I finally found the solution.

We cannot do something like this:

await Promise.all([
    coverPhoto,
    promotionalVideo
]

Instead, we should create a new Promise for each desired operation and await Promise.all for all operations.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Scalar: An Introduction: Uploading Media
Follow this guide for step-by-step instructions on importing media to your Scalar Book. Have More Questions? Have more questions? Contact ...
Read more >
Custom scalars - Apollo GraphQL Docs
The GraphQL specification includes default scalar types Int , Float , String , Boolean , and ID . Although these scalars cover the...
Read more >
2) Scalar Case Study: Bulk Uploading Images
The Widget Editorial Tool is used to insert a timeline, visualization, map, carousel, card, or summary. There is not a way to insert...
Read more >
Adding Media to Your Scalar Project
To upload your own local files, select “Upload Media File” and fill in the form to describe your image and select a file...
Read more >
File Upload - gqlgen
To use it you need to add the Upload scalar in your schema, and it will automatically add the marshalling behaviour to Go...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found