您如何通过Express访问Axios响应? [英] How do you access Axios response with Express?

查看:56
本文介绍了您如何通过Express访问Axios响应?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始使用Express,现在迷失在如何使用路由参数发出Axios请求以及如何根据请求返回的内容更改一些本地变量的问题上.这是我到目前为止的内容:

I just started working with Express and am currently lost on how to make an Axios request using route parameters and change some locals based on what the request returns. This is what I have so far:

helpers.js

helpers.js

const axios = require('axios');
const {
  titleSuffix,
  organizationPath,
  varietyPath
} = require('./constants');

let organizationData = {};
let varietyData = {};

const Helpers = {

  fetchOrganization: (organizationID) => {
    axios.get(organizationPath + organizationID)
      .then( (response) => {
        //console.log(response);
        organizationData = response.data.data;
      })
      .catch( (error) => {
        //console.log(error);
      });
      return organizationData;
  },

  fetchVariety: (varietyID) => {
    axios.get(varietyPath + varietyID)
      .then( (response) => {
        //console.log(response);
        varietyData = response.data.data;
      })
      .catch( (error) => {
        //console.log(error);
      });
      return varietyData;
  },

  setOrgOpenGraphTags: (growerHash, res) => {
    Helpers.fetchOrganization(growerHash);
    res.locals.meta.og.title = organizationData.name + titleSuffix;
    console.log('Org = ' + organizationData.name);
  },

  setVarOpenGraphTags: (contextualId, res) => {
    Helpers.fetchVariety(contextualId);
    res.locals.meta.og.title = varietyData.name + titleSuffix;
    console.log('Var = ' + varietyData.name);
  }

};

module.exports = Helpers;

server.js

server.js

// Express
const express = require('express');
const app = express();

// Helpers
const {
  setOrgOpenGraphTags,
  setVarOpenGraphTags
} = require('./helpers');

// Organization
app.get(['/org/:growerHash/*', '/_org/:growerHash/*'], (req, res) => {
  setOrgOpenGraphTags(req.params.growerHash, res);
  res.render('org');
});

我可以肯定我遗漏了一些小东西,但是似乎无法根据Axios的响应更改以下本地内容:

I'm fairly certain I'm missing something small but can't seem to get the following local changed based on the response from Axios:

res.locals.meta.og.title

基于到目前为止的知识,我如何正确访问Express中来自Axios的响应并更改本地人?我确实需要一个基于我提供的代码的答案.当前,在我的开发环境中,该请求有效,但在生产中,该请求返回"undefined".提前非常感谢.

Based on what I have so far how do I properly access the response from Axios in Express and change the locals? I really need an answer based around the code I've provided. Currently in my dev environment the request works but in production it returns "undefined". Thanks so much in advance.

推荐答案

我链接的重复项为什么我的变量在我之后没有改变在函数内部修改它? -异步代码参考,讨论为什么以及如何编写异步代码意味着您必须传播异步信息.

The duplicate that I linked, Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference, discusses why and how writing asynchronous code means that you have to propagate being asynchronous.

您现在编写的代码不会传播异步性. axios.get()返回Promise.除非所有取决于Promise解析为的值的事情实际上都在等待Promise链解析,否则您将无法获得期望的结果.

Your code, as it is written right now, does not propagate asynchronicity. axios.get() returns a Promise. Unless everything that depends on the value that that Promise resolves to actually waits for the Promise chain to resolve, you aren't going to get what you are expecting.

考虑一下您在下面评论过的代码:

Consider your code which I have commented below:

const axios = require('axios');

const Helpers = {
  fetchOrganization: (organizationID) => {
    // axios.get() will return a Promise
    // You have to wait for the Promise to finish before
    // you can use any data that it produces
    // You must propogate the Proise of data up

    // You should return axios.get(...)
    axios.get(organizationPath + organizationID)
      .then((response) => {
        //console.log(response);
        organizationData = response.data.data;
      })
      .catch((error) => {
        //console.log(error);
      });
    // This won't be populated by the time you try to use it
    return organizationData;

    // Instead do
    return axios
      .get(organizationPath + organizationID)
      .then(response => {
        const organizationData = response.data.data;
        return organizationData
      })
      .catch(err => console.error(err));

    // Better yet, do
    /*
    return axios.get(organizationPath + organizationID)
        .then(res => response.data.data) // Return is implied
        .catch(err => console.error(err));
    */
  },

  setOrgOpenGraphTags: (growerHash, res) => {
    // Nothing is coming out of this function and you aren't waiting on it
    Helpers.fetchOrganization(growerHash);

    // Instead do
    return Helpers.fetchOrganization(growerHash)
      .then(org => {
        return org.name + titleSuffix;
      });

    //res.locals.meta.og.title = organizationData.name + titleSuffix;
    //console.log('Org = ' + organizationData.name);
  }
}

// Organization
app.get(['/org/:growerHash/*', '/_org/:growerHash/*'], (req, res) => {
  // Below, you are starting the async process
  // but you don't wait for the async to finish
  // you just immediately res.render()
  setOrgOpenGraphTags(req.params.growerHash, res);
  res.render('org');

  // Instead
  setOrgOpenGraphTags(req.params.growerHash, res)
    .then(orgTitle => {
      res.locals.meta.og.title = orgTitle;
      res.render('org');
    });
});


考虑了这一点之后,让我们考虑一下代码的简化版本,它将等待Promise链解析:


After considering that, let's consider a distilled version of your code that will wait for the Promise chain to resolve:

// Let's boil your app down to it's core
const SOME_SUFFIX = "foobar";

// fetchOrganization
function getSomeData(id) {
  return axios
    .get(`http://www.example.com/things/${id}`)
    .then(thatThing => thatThing.nested.property.i.want)
    .catch(err => console.error(err));
}

// setOrgOpenGraphTags
function calculateDerivedData(id) {
  return getSomeData(id)
    .then(thatThingsProperty => `${thatThingsProperty}-${SOME_SUFFIX}`)
}

// Route
app.get("/some/endpoint/:id", (req, res) => {
  calculateDerivedData(req.params.id)
    .then(thatDerivedDataWeNeed => {
      res.locals.whatever = thatDerivedDataWeNeed;
      res.render("someTemplate");
    })
});


如果您想编写看起来更干净的东西,也可以考虑 async/await :


If you want to write something that looks arguably cleaner, you can also consider async/await:

// Let's boil your app down to it's core
const SOME_SUFFIX = "foobar";

// fetchOrganization
async function getSomeData(id) {
    try {
        const thatThing = await axios.get(`http://www.example.com/things/${id}`);
        return thatThing.nested.property.i.want;
    } catch(err){
        console.error(err);
    }
}

// setOrgOpenGraphTags
async function calculateDerivedData(id) {
    const thatThingsProperty = await getSomeData(id);
    return `${thatThingsProperty}-${SOME_SUFFIX}`;
}

// Route
app.get("/some/endpoint/:id", async function(req, res) => {
  res.locals.whatever = await calculateDerivedData(req.params.id);
  res.render("someTemplate");
});

这篇关于您如何通过Express访问Axios响应?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆