How can I use data from app.post in app.get?

How can I use data from app.post in app.get?
0

#1

Hi everyone,
I’m building a react dictionary app that gets data from the user in a component (Input.js) and sends it to the server.js (app.post). Inside this request I have a nested request to the external API, where it gets the results. I had to put it inside the app.post because of course I don’t have access to the user input I got from the POST request outside of it.

Then, to send the results to the frontend (App.js), I have an app.get request that is called from componentDidMount. The problem is of course that this get request doesn’t have access to the results from the post request, and I cannot nest them or call the get request from inside the then(). localStorage doesn’t work either inside requests.

I had to build a node/express backend to fetch data from the API because I had a bunch of issues with Authentication and CORS and this was the only thing that worked.

Can anyone help me with this? I’m a newbie and I’m getting a headache already. Thanks in advance!

Here’s my server.js code:

const express = require('express');
const app = express();
const request = require('request');
const port = process.env.PORT || 5000;
var rp = require('request-promise');

app.use(express.static('public'));
require('dotenv').config();

// create a POST route

function makeUrl(word_id, baseUrl, source_lang) {
  return baseUrl + source_lang + '/' + word_id.toLowerCase();
}

app.post('/express_backend/:word_id', (req, res) => {
  //console.log(req.params)
  res.send('success')
  var word_id = req.params.word_id;
  var baseUrl = 'https://od-api.oxforddictionaries.com:443/api/v1/entries/';
  var source_lang = 'en';
  var url = makeUrl(word_id, baseUrl, source_lang);
  url = encodeURI(url);
  //console.log('url:', url)
      var options = {
      url,
      headers: {
        'app_id': process.env.APP_ID, 
        'app_key': process.env.APP_KEY,
        'Host': process.env.HOST,
        'Cache-Control': 'no-cache',
        'Postman-Token': process.env.POSTMAN_TOKEN
      }
    };

    //get definitions and pronunciation
  var results = [];
    rp.get(options, function(error, response, body){
      if (error) {
        return 'Not Found'
      }
     }).then(function(body){
          var data = JSON.parse(body)
          var lexicalEntries = data.results[0].lexicalEntries;
            lexicalEntries.forEach(function(entry) {
              entry.entries.forEach(function(item){ results.push(item.senses[0].definitions) });
              //var audioFile = entry.pronunciations.forEach(function(item){console.log(item.audioFile)});
             })
          console.log(results)
          return results;
     }).catch(function(error){
      if (error.statusCode == 404){
        results = 'No entries found for ' + word_id;
        console.log(results);
        return results;
      }
    })
});

app.listen(port, () => console.log(`Listening on port ${port}`));

// create a GET route
app.get('/express_backend', (req, res) => {
  res.send({ express: results });
});

And in the App.js, I have this to fetch the data from the backend. It worked perfectly before I made the POST request so I know that my only problem is not being able to pass the data from one request to the other:

  componentDidMount() {
      // Call our fetch function below once the component mounts
    this.callBackendAPI()
      .then(res => this.setState({ data: res.express }))
      .catch(err => console.log(err));
  }

    // Fetches our GET route from the Express server. (Note the route we are fetching matches the GET route from server.js
  callBackendAPI = async () => {
    const response = await fetch('/express_backend');
    const body = await response.json();

    if (response.status !== 200) {
      throw Error(body.message) 
    }
    return body;
  };

#2

This is a GET request:

const response = await fetch('/express_backend');

To make a POST request you can write:

const response = await fetch('/express_backend', {method: 'POST);

#3

so you’re saying to get the user input i do that before my get request inside componentDidMount instead of a separate POST? I’m sorry, I’m confused!


#4

I’m saying the fetch method you’re using by default send a GET request ( that’s why

It worked perfectly before I made the POST request

i think): if you want to send a POST request you have to set it explicit ( as showed in the snippet above) ^^

More on that, if you want to send a POST request you would send along some data ( otherwise you could use a GET ): you can specify it in the same ‘options’ object, something like:

const response = await fetch('/express_backend', {method: 'POST', body: JSON.stringify(myData));

EDIT:
Looking at your code seems you’re not sending back your data, only a ‘success’ string;

app.post('/express_backend/:word_id', (req, res) => {
  //console.log(req.params)
  res.send('success')
  var word_id = req.params.word_id;

...
 
          console.log(results)
          return results;

Remove this res.send('success') and replace your return result statement with res.status(200).json(result) which send back to the client your results data.

From the client side:

callBackendAPI = async () => {
    const response = await fetch('/express_backend/' + iAmTheWordId);
    const body = await response.json();

    if (response.status !== 200) {
      throw Error(body.message) 
    }
console.log(body);
    return body;
  };

Here you change the path passed to fetch and then you should able to log in the client the body variable.

That said here and there there are few weird thing: you use url parameter into a post request without a body (so, looking the second snippet of this post you could move the url param inside the body and send a request without params)