【问题标题】:Express how to pass value from .js promise to .ejs view表达如何将值从 .js 承诺传递到 .ejs 视图
【发布时间】:2021-03-13 19:00:30
【问题描述】:

我试图将值从路由 js 文件 (auth.js) 传递到 ejs 视图 (dashboard.ejs)

这是 auth.js 中的代码:

const express = require("express");
const google = require('googleapis').google;
const jwt = require('jsonwebtoken');
const CONFIG = require("../config/passport-google");

const nf = require('node-fetch');

const router = express.Router();

// Google's OAuth2 client
const OAuth2 = google.auth.OAuth2;

router.get("/youtube", function(req, res) {
  // Create an OAuth2 client object from the credentials in our config file
  const oauth2Client = new OAuth2(
    CONFIG.oauth2Credentials.client_id,
    CONFIG.oauth2Credentials.client_secret,
    CONFIG.oauth2Credentials.redirect_uris[0]
  );

  // Obtain the google login link to which we'll send our users to give us access
  const loginLink = oauth2Client.generateAuthUrl({
    access_type: "offline", // Indicates that we need to be able to access data continously without the user constantly giving us consent
    scope: CONFIG.oauth2Credentials.scopes // Using the access scopes from our config file
  });
  return res.render("./home/g-login", { loginLink: loginLink });
});

router.get("/youtube/callback", function(req, res) {
  // Create an OAuth2 client object from the credentials in our config file
  const oauth2Client = new OAuth2(
    CONFIG.oauth2Credentials.client_id,
    CONFIG.oauth2Credentials.client_secret,
    CONFIG.oauth2Credentials.redirect_uris[0]
  );

  if (req.query.error) {
    // The user did not give us permission.
    return res.redirect("/");
  } else {
    oauth2Client.getToken(req.query.code, function(err, token) {
      if (err) return res.redirect("/");

      // Store the credentials given by google into a jsonwebtoken in a cookie called 'jwt'
      res.cookie("jwt", jwt.sign(token, CONFIG.JWTsecret));
      
      // return res.redirect("/get_some_data");

      if (!req.cookies.jwt) {
        // We haven't logged in
        return res.redirect("/");
      }
    
      // Add this specific user's credentials to our OAuth2 client
      oauth2Client.credentials = jwt.verify(req.cookies.jwt, CONFIG.JWTsecret);
    
      // Get the youtube service
      const service = google.youtube("v3");

      const url = `https://www.googleapis.com/oauth2/v1/userinfo?access_token=${token[Object.keys(token)[0]]}`;

      const get_data = async () => {
        try {
          const response = await nf(url);
          const json = await response.json();
          return await json;
        } catch (error) {
          console.log(error);
        }
      };

      const diomerda = get_data();

      module.exports = {
        diomerda
      }
      
      // Get 50 of the user's subscriptions (the channels they're subscribed to)
      service.subscriptions
        .list({
          auth: oauth2Client,
          mine: true,
          part: "snippet,contentDetails",
          maxResults: 50
        })
        .then(response => {
          //console.log(response.data.items[0].snippet.resourceId)

          // Render the profile view, passing the subscriptions to it
          return res.render("./user/dashboard", { subscriptions: response.data.items, diomerda: diomerda });
        });

    });
  }
});

// Logout from Google
router.get('/logout', (req, res) => {
  req.logout();
  res.redirect('/');
})

module.exports = router;

diomerda 变量是一个承诺,我已经通过 service.subscriptions 下面的函数呈现视图(它正确地将订阅值发送到仪表板视图)所以我怎样才能也将我的 diomerda 变量传递给该视图?

我正在尝试使用 module.exports,正如您在代码中看到的那样,但我似乎无法在 ejs 文件中使用 require

dashboard.ejs 是:

<h6>Profile dashboard</h6>
<h3>Welcome</h3>
<p>Here are your favorites channels</p>
<% var params = require('../routes/auth')   
    console.log(params.diomerda);
  %>

【问题讨论】:

    标签: javascript node.js express routes ejs


    【解决方案1】:

    请在以下代码中找到mark1和mark2。

    mark1:你不需要导出这个方法,在渲染你的ejs视图之前使用它。而且当你在这个函数中返回你的json时,你不需要在这里添加额外的等待。

    mark2:我将get_data 函数放在这里,因为我看到您在router.get("/youtube/callback") 的代码末尾将ejs 呈现给用户。因此,在将 ejs 视图呈现给用户之前,您需要调用 get_data 函数来获取您想要的数据。然后,只需用数据渲染它。

    router.get("/youtube/callback", function(req, res) {
        // Create an OAuth2 client object from the credentials in our config file
        const oauth2Client = new OAuth2(
          CONFIG.oauth2Credentials.client_id,
          CONFIG.oauth2Credentials.client_secret,
          CONFIG.oauth2Credentials.redirect_uris[0]
        );
      
        if (req.query.error) {
          // The user did not give us permission.
          return res.redirect("/");
        } else {
          oauth2Client.getToken(req.query.code, function(err, token) {
            if (err) return res.redirect("/");
      
            // Store the credentials given by google into a jsonwebtoken in a cookie called 'jwt'
            res.cookie("jwt", jwt.sign(token, CONFIG.JWTsecret));
            
            // return res.redirect("/get_some_data");
      
            if (!req.cookies.jwt) {
              // We haven't logged in
              return res.redirect("/");
            }
          
            // Add this specific user's credentials to our OAuth2 client
            oauth2Client.credentials = jwt.verify(req.cookies.jwt, CONFIG.JWTsecret);
          
            // Get the youtube service
            const service = google.youtube("v3");
      
            const url = `https://www.googleapis.com/oauth2/v1/userinfo?access_token=${token[Object.keys(token)[0]]}`;
      
            // ================ mark 1 ====================
            const get_data = async () => {
              try {
                const response = await nf(url);
                const json = await response.json();
                return json;
              } catch (error) {
                console.log(error);
              }
            };
      
            // Get 50 of the user's subscriptions (the channels they're subscribed to)
            service.subscriptions
              .list({
                auth: oauth2Client,
                mine: true,
                part: "snippet,contentDetails",
                maxResults: 50
              })
              // ================ mark 2 ====================
              // remember to add async here
              .then(async (response) => { 
                 // ================ mark 2 ====================
                 const diomerda = await get_data()
      
                // Render the profile view, passing the subscriptions to it
                return res.render("./user/dashboard", { subscriptions: response.data.items, diomerda: diomerda });
              });
      
          });
        }
      });
    

    【讨论】:

    • 嗨,你的意思是“//在你的服务订阅中需要它”,service.subscriptions已经在auth.js里面,上面所有的代码都在auth.js里面
    • “服务”是在我显示的代码正上方声明的变量,其中 const service = google.youtube("v3");因为我在 auth.js 中需要“googleapis”
    • 我以为是不同的文件。能贴一下完整的js文件吗?
    • 用完整代码编辑。我这样做的原因是因为 youtube v3 api 不返回用户信息,所以我不得不使用我从 youtube oauth 获得的令牌并使用它来进行 userinfo api 调用,并且异步 js shitfest 开始了
    • 谢谢你真棒。我还用你的标记更好地理解了 async/await 的逻辑。
    猜你喜欢
    • 2020-04-22
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-03
    • 2017-07-09
    • 1970-01-01
    • 2022-01-05
    相关资源
    最近更新 更多