Search code examples
node.jsexpressamazon-s3responsebusboy

Failing to get a response back from a web api call in node


this particular Node issue has been driving me crazy for going on a week.

I have to create a layer of friction (a modal that asks the user if they're sure) in the process of a csv file upload. Essentially, the flow will be:
User Clicks 'UPLOAD SPREAD SHEET' > File uploads to s3 > S3 returns a reference key > Pass reference key into micro service web api to evaluate > if true => ask user 'if they're sure' > If user is sure continue uploading > pass reference key onward to another endpoint, same service, to finish the upload. false return would continue on to the upload with no modal.

its kind of a silly product-based functionality that makes a show of alerting the user to potential duplicate entries in their spreadsheet since we can't currently detect duplicate entries ourselves.

Problem is, I can't get a response to return from the evaluation to save my life. If I console.log the response, I can see it in Node's terminal window but nothing comes back in the network tab for the response. I'm not sure if it's because it's a file upload, if it's busyboy, if it's just not the right syntax for the response type but endless googling has brought me no answers and I'd love it if someone more experienced with Node and Express could take a look.

router.post('/import/csv',
  // a bunch of aws s3 stuff to upload the file and return the key
      s3.upload(uploadParams, (err, data) => {
        if (err) {
          res.status(500).send({
            error_message: 'Unable to upload csv. Please try again.',
            error_data: err
          });
        } else if (data) {
        // creating the key object to pass in
          const defaultImportCheck = {
            body: data.Key
          };
          // endpoint that will evaluate the s3 reference key
          SvcWebApiClient.guestGroup.defaultImportCheck(defaultImportCheck)
            .then((response) => {
              if (response.status === 'success') {
                // where the response should be. this works but doesn't actually send anything.
                res.send(response);
              } else {
                const errorJson = {
                  message: response.message,
                  category: response.category,
                  trigger: response.trigger,
                  errors: response.errors
                };

                res.status(500).send(errorJson);
              }
            })
            .catch((error) => {
              res.status(500).send({
                error_message: 'Unable to upload csv. Please try again.',
                error_data: error
              });
            });
        }
      });
    });
    req.pipe(busboy);
  }
);

Solution

  • Got it, for anyone that ends up having my kind of problem. It's a two parter so buckle up.

    1) the action function that handles the response on the react side didn't convert the response into json. Apparently, what would get returned is a "readable stream" which should have then converted to json. it didn't.

    2) the response itself needed to be in json as well.

    so from the action function:

    export function csvUpload(file) {
      do some stuff
      return fetch(fetch some stuff) { with some parameters }
        .then(some error stuff)
        .then(response => response.response.json())
    }
    

    then from the post request:

    if (response.status === "success") {
      res.json({ valid: response.data, token: data.Key)};
    }
    

    this returns an object with what I need back to the client. hope this helps someone else.