如何使用 Express 访问 Axios 响应? [英] How do you access Axios response with Express?

查看:17
本文介绍了如何使用 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

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

// 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 的响应并更改本地人?我真的需要一个基于我提供的代码的答案.目前在我的开发环境中,请求有效,但在生产中它返回未定义".非常感谢.

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:

// 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天全站免登陆