【问题标题】:Sending data from Express to React via Contentful API通过 Contentful API 从 Express 发送数据到 React
【发布时间】:2016-11-10 22:05:27
【问题描述】:

我决定试用 contentful 的无头 CMS,但我遇到了他们的 API 客户端问题。我想要做的是将 express 与服务器端渲染的 react 结合起来,我使用 this repo 作为我的起点。

我的高速路由器

创建一个我的 React 组件可以调用的路由:

createApiRouter(app) {
    const router = express.Router();

    this.createHeroesRoute(router);
    // this.createDetailedBillRoute(router);        
    return router;
},

createHeroesRoute(router) {
    router.get('/get-heroes', (req, res) => {
      this.getHeroes((err, data) => {
        if(!err) {
          res.json(data);                                    
        } else {
          res.status(500).send(err);
        }
      });
    });
},

从 Contentful 获取数据

getHeroes(callback) {
    contentfulClient.getEntries({content_type: 'sectionHeroes'})
      .then((entries) => {
        //serilizations is a custom data serializer to format this data, it's working fine
        return JSON.parse(serializations.serializeMainSection(entries.items[0]))
      })
      .catch((error) => error );
}

我的反应组件

请求数据

static requestData(params, domain = '') {
    return axios.get(`${domain}/api/get-heroes`);
}

将组件的状态设置为接收到的数据

componentDidMount() {
    this.constructor.requestData().then((response) => {
      this.setState(response.data);
    }).catch((err) => {
      throw new Error(err);
    });
}

故障点发生在 express 内部的 getHeroes 方法中。因为 contentful 的客户是一个承诺,我不确定如何让getHeroesRoute 等待来自getHeroes 的返回。我该怎么做?

【问题讨论】:

  • 我已经放弃使用 Contentful 的 api 客户端,而是使用 node-rest-client 并自己构建 Contentful 的抽象。我仍然想确切地知道为什么 contentful 基于承诺的响应不起作用,但这对我来说不再是成败的问题。

标签: javascript express reactjs es6-promise contentful


【解决方案1】:

当 promise 解决时,您需要调用 createHeroesRoute() 传递给 getHeroes() 的回调。将 getHeroes() 更改为此应该可以:

getHeroes(callback) {
    contentfulClient.getEntries({content_type: 'sectionHeroes'})
        .then((entries) => {
            callback(JSON.parse(serializations.serializeMainSection(entries.items[0])));
        })
       .catch((error) => error );
}

假设 JSON.parse 一切正常。

【讨论】:

  • 感谢您的回复。将其更改为现在只会呈现一个空对象...这很奇怪。
  • 实际上,将其更改为会产生语法错误,尽管我的终端并没有告诉我错误发生在哪里。
  • 您需要逐步调试。我不知道什么序列化。 serializeMainSection() 确实如此,也不是 entry.items[0] 包含的内容。我建议对您尝试执行的所有操作进行增量记录。像这样: contentfulClient.getEntries({content_type: 'sectionHeroes'}) .then((entries) => { callback(JSON.parse(serializations.serializeMainSection(entries.items[0]))); }) .catch( (错误) => 错误);
  • 结果很混乱,显然 SO 不像在答案中那样格式化 cmets 中的代码。无论如何,我会 console.log 每一步,看看发生了什么。立即执行console.log(entries); 以确保您获得预期的数据,它需要是一个包含数组 .items 的对象,其中至少包含一个项目。如果看起来不错,请确保 serializeMainSection() 函数返回 JSON 字符串,否则 JSON.parse 会阻塞。
  • 是的,我遗漏了一些东西,因为我已经做了你提议的那些事情。问题是 contentful 的客户端并没有按照服务器期望的方式返回数据。让您感到困惑的东西是我以我认为服务器想要的方式序列化数据(并且它成功了)但是内容的客户端然后返回了服务器试图运行的空承诺 - 导致没有任何工作。
【解决方案2】:

这不是 API 的问题,在发送响应之前,您无需等待承诺解决。您的代码应如下所示:

getHeroes() {
  return contentfulClient.getEntries({content_type: 'sectionHeroes'})
    .then((entries) => {
      //serilizations is a custom data serializer to format this data, it's working fine
      return JSON.parse(serializations.serializeMainSection(entries.items[0]))
    })
}

在您的快速路由器中:

createApiRouter(app) {
  const router = express.Router();

  this.createHeroesRoute(router);
  // this.createDetailedBillRoute(router);        
  return router;
},

createHeroesRoute(router) {
  router.get('/get-heroes', (req, res) => {
    this.getHeroes().then((data) => {
      res.json(data);
    }).catch((err) => {
       res.status(500).send(err);
    })
  });
}

【讨论】:

    猜你喜欢
    • 2018-09-11
    • 2021-03-20
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2022-01-28
    • 1970-01-01
    • 2017-11-23
    相关资源
    最近更新 更多