Скрипт React Callservice не извлекает необходимую информацию из Node.js скрипт, который вызывает API

#javascript #node.js #reactjs #rest

Вопрос:

Я пытаюсь создать простую веб-страницу с помощью React.js для отображения информации, полученной из API. Я говорю просто, потому что так и должно быть, но я уже давно ничего не разрабатывал, и, похоже, у меня проблема, причину которой я не могу найти.

Я сделал node.js файл, чтобы выступать посредником между моей веб-страницей и API, потому что у меня возникли проблемы с CORS.

Ситуация:

Всякий раз, когда я нажимаю на кнопку, я не получаю никакой информации. Вызов продолжает отображать «ожидание» в качестве статуса на вкладке «Сеть» (см. Изображение ниже). введите описание изображения здесь

Но в моих Node.js сценарий, который я вижу, регистрируя, я получаю правильный ответ и получаю всю необходимую мне информацию. Таким образом, я могу заявить, что мой скрипт узла работает так, как должен.

Я думаю, что проблема заключается в том, что обмен с моей Node.js сценарий и CallService.js сценарий. Я просто не могу понять, в чем дело.

Что я здесь упускаю?

Я предоставил весь код, который у меня есть ниже, но опустил конфиденциальную информацию.

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}`));

 

Я сделал Callservice.js файл в моем приложении react:

 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;
      });;
  };

 

В своем приложении я сделал кнопку, которая должна вызывать API и предоставлять полученную информацию в консоли.

 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:

Твоя проблема здесь:

 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;
    }
  )
});
 

Он находится в ожидании, потому что на него никогда нет ответа.
Когда он переходит к вашей конечной точке ‘ListAllModels’, он асинхронно делает запрос к другой конечной точке.
Когда ответ возвращается, он больше не находится внутри app.get функции.

Кроме того, функция return response вернет ответ вызывающему абоненту этого обратного вызова, который находится внутри request() функции. Вам нужно отправить ответ обратно на ваш CallService объект, использующий res объект.

Вы могли бы завернуть это в обещание.

Вам нужно отправить ответ, используя res объект, который передается в качестве параметра. Этот объект представляет ответ, отправленный сервером узла. Единственный способ, которым клиент может что-либо получить, — это если вы отправите что-то через этот объект с помощью res.send(data) . Использование return response; не работает, потому что оно находится внутри другой функции. Он будет возвращен вызывающему объекту этой функции, а не родительской функции 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();
    });
});
 

Комментарии:

1. app.get('/ListAllModels', (req, res) => { (async () => { await fetch( '{{url}}',{ headers: { 'Content-Type': 'application/xml', 'X-Tenant-ID': '{{tenant-ID}}', 'Authorization': 'Basic {{auth}}' }}).then(res => {return res}); console.log(res); })(); });

2. @imkeVr я немного исправил ваш комментарий в своем ответе. Если вы отправите другой ответ напрямую, клиент получит ответ, завернутый в ответ, поэтому вам нужно будет это исправить.

3. @imkeVr Ты это понял?