React Callservice script doesn't retrieve the needed information from Node.js script that makes the API call

Viewed 33

I'm trying to make a simple webpage using React.js to display information retrieved from an API. I say simple because it should be, but I haven't developed anything for a long time and I seem to have an issue that I can't find the cause off.

I made a node.js file to act as a mediator between my webpage and the API because I was having CORS issues.

Situation:

Whenever I push the button I don't retrieve any information. The call keeps displaying "pending" as status within the network tab(see below image). enter image description here

But within my Node.js script I can see by logging that I do get the correct response and retrieve all the information I need. So I can state that my node script works as it should.

I think the issue is situated between the exchange from my Node.js script and the CallService.js script. I just can't put my finger on what is wrong.

What am I missing here?

I've provided all the code I have below but left out sensitive information.

Node.js:

const express = require('express');
const request = require('request');

const app = express();

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  next();
});

app.get('/ListAllModels', (req, res) => {
  request(
    {
      url: '/* api url*/',
      headers: {
        'Content-Type': 'application/xml',
        'X-Tenant-ID': '/*tenant id*/',
        'Authorization': 'Basic /*authorization*/'
      }
    },
    (error, response, body) => {
      if (error || response.statusCode !== 200) {
        return res.status(500).json({ type: 'error', message: err.message });
      }

      console.log(response);
     return response;
    }
  )
});

const PORT = process.env.PORT || 4000;
app.listen(PORT, () => console.log(`listening on ${PORT}`));

I made a Callservice.js file in my react app:

import axios from 'axios';

export const getAllEmailModels = () => {
    return axios.get("http://localhost:4000/ListAllModels").then(response => {
       if (response.statusCode === 200) {
        return response;
       }
    throw new Error("Network response was not ok.");
    }).catch(error => {
        return error;
      });;
  };

In my app I made a button that should call on the API and provide the retrieved information in console.

import React, { Component } from 'react'
//import axios from 'axios';
import * as CallService from "../Services/CallService";


export default class Login extends Component {
    constructor(props) {
        super(props);
        this.state = {emailModels:[]};
    
        this.emailModelTest = this.emailModelTest.bind(this);
      }


      emailModelTest() {
          console.log("button works");
        CallService.getAllEmailModels().then(response => this.setState({
            emailModels:  response.body,
        }), console.log(this.state.emailModels) );

        
    }


    render() {
        
        return (
            <div>
            <button onClick={this.emailModelTest}>test call</button>
        </div>
        )
    }
}
1 Answers

Your problem is in here:

app.get('/ListAllModels', (req, res) => {
  request(
    {
      url: '/* api url*/',
      headers: {
        'Content-Type': 'application/xml',
        'X-Tenant-ID': '/*tenant id*/',
        'Authorization': 'Basic /*authorization*/'
      }
    },
    (error, response, body) => {
      if (error || response.statusCode !== 200) {
        return res.status(500).json({ type: 'error', message: err.message });
      }

      console.log(response);
     return response;
    }
  )
});

It's pending because it there is never a response. When it goes to your 'ListAllModels' endpoint, it makes a request to another endpoint asynchronously. When the response comes back it isn't inside the app.get function anymore.

Also, the return response will return the response to the caller of that callback which is inside the request() function. You need to send the response back to your CallService using the res object.

You could wrap it in a promise.

You need to send the response using the res object that is passed in as a parameter. That object represents the response send by the node server. The only way the client can get anything is if you send something through that object using res.send(data). Using return response; doesn't work because it's inside another function. It will be returned to the caller of that function not the parent function app.get()

app.get('/ListAllModels', (req, res) => {
    fetch('{{url}}', {
      headers: {
        'Content-Type': 'application/xml',
        'X-Tenant-ID': '{{tenant-ID}}',
        'Authorization': 'Basic {{auth}}'
      }
    }).then(otherRes => {
      res.status(200).send(otherRes);
    }).error(error => {
        res.status(400).end();
    });
});
Related