【问题标题】:How do I make hbs render an array from a callback function?如何让 hbs 从回调函数中渲染数组?
【发布时间】:2019-09-04 20:45:39
【问题描述】:

目前我有 axios 和cheerio 从网页返回数据。然后我设置 express 来设置一些视图。我仔细检查了我的 index.hbs,它在正文中包含 {{data}}。这应该允许页面从索引渲染数据渲染文本: deals 。我错过了什么吗?交易 obj 包含 4 个我可以访问的不同对象。

getdeals(result => console.log(result.totaldeals[0].date))

这将在控制台中返回 [ 09/04/2019/ ]。

const path = require('path')
const express = require('express')
const hbs = require('hbs')
const axios = require('axios');
const cheerio = require('cheerio');

const app = express()

// Define paths for express config
const publicDirPath = path.join(__dirname, '../public')
const viewsPath = path.join(__dirname, '../templates/views')
const partialsPath = path.join(__dirname, '../templates/partials')

// Setup handlebars engine and views location
app.set('view engine', 'hbs')
app.set('views', viewsPath)
hbs.registerPartials(partialsPath)

// Setup static directory to serve
app.use(express.static(publicDirPath))


// Views
app.get('', (req, res) => {
    res.render('index', {
        title: 'ClearVision',
        data: dealss,
        name: 'Chris'
    })
})

app.get('/about', (req, res) => {
    res.render('about', {
        title: 'ClearVision - About Us',
        header: 'About Us',
        name: 'Chris'
    })
})

app.get('/help', (req, res) => {
    res.render('help', {
        title: 'ClearVision - Help',
        helptext: 'Please contact x for help.',
        name: 'Chris'
    })
})

app.get('/weather', (req, res) => {
    res.send({
        forecast: 'It is sunny.',
        location: 'x, Ca'
    })
})

app.listen(1337, () => {
    console.log('Server is currently running on port 1337.')
})

const url = 'https://abcdef.com/';
axios.defaults.withCredentials = true


// Get the deals
const getdeals = (callback) => {
    axios(url, {
            headers: {
                Cookie: "x=xx;"
            }
        })
        .then(response => {
            const html = response.data;
            const $ = cheerio.load(html);

            // Deals Page
            const statsTable = $('tbody > tr');
            const totaldeals = [];


            // Loop Table for data in each row
            statsTable.each(function () {
                const nwline = "\n"
                let date = $(this).find('td:nth-child(1)').text()
                let bodydeals = $(this).find('td:nth-child(2)').text()
                let newdeal = $(this).find('td:nth-child(3)').text()
                let revdeal = $(this).find('td:nth-child(4)').text()
                let monthlydealrev = $(this).find('td:nth-child(5)').text()

                // Clear /n
                if (date.includes(nwline)) {
                    date = date.toString().replace("\n", ""),
                        date = date.toString().replace("\n", "")
                }

                // Clear /n
                if (bodydeals.includes(nwline)) {
                    bodydeals = bodydeals.toString().replace("\n", ""),
                        bodydeals = bodydeals.toString().replace("\n", ""),
                        bodydeals = bodydeals.toString().replace("\n", "")
                }

                // Clear /n
                if (newdeal.includes(nwline)) {
                    newdeal = newdeal.toString().replace("\n", ""),
                        newdeal = newdeal.toString().replace("\n", ""),
                        newdeal = newdeal.toString().replace("\n", "")
                }

                // Clear /n
                if (revdeal.includes(nwline)) {
                    revdeal = revdeal.toString().replace("\n", ""),
                        revdeal = revdeal.toString().replace("\n", ""),
                        revdeal = revdeal.toString().replace("\n", "")
                }

                // Clear /n (lookup jquery table functions)
                if (monthlydealrev.includes(nwline)) {
                    monthlydealrev = monthlydealrev.toString().replace("\n", ""),
                        monthlydealrev = monthlydealrev.toString().replace("\n", ""),
                        monthlydealrev = monthlydealrev.toString().replace("\n", "")
                }

                totaldeals.push({
                    date,
                    bodydeals,
                    newdeal,
                    revdeal,
                    monthlydealrev
                })



            })
            callback({
                totaldeals
            })
            //console.log(totaldeals[1].date)
        })
        .catch(console.error);

}

function newFunction() {[getdeals(result => console.log(result.totaldeals))]}

我在 res.render 下为索引添加了一个 data: Deals。我还检查了其中有 {{data}} 的 index.hbs。这不应该只是将文本添加到屏幕上吗?

关于如何将其打印到视图的任何想法?

【问题讨论】:

  • 所以您希望将getdeals 的结果传递给dealss
  • @slebetman 基本上是的,我有一个对象(结果),它有一个数组(totaldeals),我不能让我的路由正确处理它到我的 hbs 文件。 function newFunction() {[getdeals(result => console.log(result.totaldeals))]} 需要将其传递给交易(它不一定是交易,但我尝试用newFunction() 替换我的路线所在的交易,确保它打印到控制台,但这不是我想要的。我不'不希望它打印到控制台我希望它给我数据/字符串,以便我可以在网页上输出它..
  • @slebetman function newFunction() { return [getdeals(result => JSON.stringify(result.totaldeals[0].newdeal))] } 我也试过了,但没有运气

标签: javascript node.js express axios handlebars.js


【解决方案1】:

您只需将其作为变量传递给您的 hbs 文件:

app.get('', (req, res) => {
    getdeals(result => {
        res.render('index', {
            title: 'ClearVision',
            data: result, // or result.totaldeals depending
            name: 'Chris' // on what you really mean
        })
    });
})

改进

如果您重写 getdeals() 以返回 Promise 而不是接受回调,您可以使用 async/await

const getdeals = () => {
    // NOTE THIS CHANGE, return axios promise:
    return axios(url, {
            /* ... */
        })
        .then(response => {
            /* .. */
            statsTable.each(function () {
                /* .. */
            })

            return totaldeals; // NOTE we return the result instead
                               // of calling a callback. This will
                               // return a resolved Promise
        })
        // Don't catch here, your request will hang if an error occurs
}

现在通过上面的更改(返回 axios 并返回结果)我们可以将路由重写为:

app.get('', async (req, res, next) => { // must have async keyword!
    try {
        let result = await getdeals();

        res.render('index', {
            title: 'ClearVision',
            data: result, // or result.totaldeals depending
            name: 'Chris' // on what you really mean
        })
    }
    catch (err) {
        console.log(err);
        next(err); // this will close the request socket
    }
})

【讨论】:

  • 你太棒了,先生。谢谢 :D 我要剖析那个 promise 代码(还没有学到太多关于异步的知识)
猜你喜欢
  • 2020-01-21
  • 2020-08-27
  • 2015-11-20
  • 2017-03-25
  • 1970-01-01
  • 1970-01-01
  • 2019-11-22
  • 2018-05-04
  • 2021-07-02
相关资源
最近更新 更多