React和NodeJS:如何使用从Client上的Server接收的数据?

时间:2018-09-29 18:06:41

标签: javascript node.js reactjs mailchimp-api-v3.0 next.js

我想使用客户端上从服务器接收的数据。我将NodeJS服务器与NextJS和React一起使用。

我在服务器上使用此功能:

function addEmailToMailChimp(email, callback) {
    var options = {
        method: 'POST',
        url: 'https://XXX.api.mailchimp.com/3.0/lists/XXX/members',
        headers:
        {
            'Postman-Token': 'XXX',
            'Cache-Control': 'no-cache',
            Authorization: 'Basic XXX',
            'Content-Type': 'application/json'
        },
        body: { email_address: email, status: 'subscribed' },
        json: true
    };
    request(options, callback);
}

此功能将从此时开始运行:

server.post('/', (req, res) => {
            addEmailToMailChimp(req.body.email, (error, response, body) => {
                // This is the callback function which is passed to `addEmailToMailChimp`
                try {
                    var respObj = {}; //Initial response object
                    if (response.statusCode === 200) {
                      respObj = { success: `Subscribed using ${req.body.email}!`, message: JSON.parse(response.body) };
                    } else {
                      respObj = { error: `Error trying to subscribe ${req.body.email}. Please try again.`, message: JSON.parse(response.body) };
                    }
                    res.send(respObj);
                  } catch (err) {
                    var respErrorObj = { error: 'There was an error with your request', message: err.message };
                    res.send(respErrorObj);
                  }
            });
        })

try方法用于验证电子邮件地址是否可以成功保存到MailChimp。一条适当的消息发送给客户端。

在客户端,我使用此功能从服务器接收和显示数据:

handleSubmit() {
        const email = this.state.email;
        this.setState({email: ""});
        fetch('/', {
            method: 'POST',
            headers: {
              'Accept': 'application/json',
              'Content-Type': 'application/json'
            },
            body: JSON.stringify({email:email}),
          }).then(res => {
            if(res.data.success) {
              //If the response from MailChimp is good...
              toaster.success('Subscribed!', res.data.success);
              this.setState({ email: '' });
            } else {
              //Handle the bad MailChimp response...
              toaster.warning('Unable to subscribe!', res.data.error);
            }
          }).catch(error => {
            //This catch block returns an error if Node API returns an error
            toaster.danger('Error. Please try again later.', error.message);
          });
      }

问题:电子邮件地址已成功保存在MailChimp中,但始终显示消息:'Error. Please try again later.'来自.catch区域。当我从捕获区域记录错误时,我得到以下信息:

TypeError: Cannot read property 'success' of undefined

我的错误在哪里?我在Node.js环境中经验不足。如果您能给我具体解决方案,我将不胜感激。谢谢您的答复。

3 个答案:

答案 0 :(得分:0)

对于fetch,响应上没有数据属性。您必须致电res.json()并兑现承诺。从那里将读取并反序列化响应主体。

答案 1 :(得分:0)

handleSubmit() {
        const email = this.state.email;
        this.setState({email: ""});
        fetch('/', {
            method: 'POST',
            headers: {
              'Accept': 'application/json',
              'Content-Type': 'application/json'
            },
            body: JSON.stringify({email:email}),
          })
         .then(res => {
            console.log(res); //to make sure the expected object is returned
            if(res.data.success) {
              //If the response from MailChimp is good...
              toaster.success('Subscribed!', res.data.success);
              this.setState({ email: '' });
            } else {
              //Handle the bad MailChimp response...
              toaster.warning('Unable to subscribe!', res.data.error);
            }
          }).catch(error => {
            //This catch block returns an error if Node API returns an error
            toaster.danger('Error. Please try again later.', error.message);
          });
      }

答案 2 :(得分:0)

您需要更改的两件事:

  1. 调用并等待res.json()将响应主体作为json对象。
  2. 1的结果是您可以直接使用的“数据”对象

handleSubmit() {
    //...
    fetch('/', {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({email:email}),
      })
      .then(res => res.json())
      .then(data => {
        if(data.success) {
          //...
          toaster.success('Subscribed!', data.success);
        } else {
          toaster.warning('Unable to subscribe!', data.error);
        }
      }).catch(error => {
        //...
      });
  }