无法将node.js中方法的正确值返回给ejs模板

时间:2016-11-29 06:12:47

标签: javascript node.js express ejs

在app.js中,在社交对象内部,随时我在console.log中的totalcount,我能够在终端中看到正确的值。但是当我尝试在index.ejs中查看这些值时,它们都是未定义的。这是为什么?

app.js

var express = require('express');
var multer = require('multer');
var bodyParser = require('body-parser');
var mysql = require('mysql');
var database = require('./middleware/database');
var upload = require('./uploads/upload');
var socialAPIs = require('./socialAPIs/social');
var app = express();

app.get('/middlePage/:id', function(req, res) {
      if (req.body.keys === undefined) {
        database.connection.query('select * from spotlights where id = ?', req.params.id + ';', function(err, result) {
          if (err) {
            console.error(err);
            return;
          } else if (result[0]) {
            var currentSpotlight = {
              projectName: result[0].projectName,
              interviewee: result[0].interviewee,
              imageUrl: result[0].imageUrl,
              bio: result[0].bio,
              tags: result[0].tags,
              facebook: result[0].facebook,
              instagram: result[0].instagram,
              twitter: result[0].twitter,
              youtube: result[0].youtube,
              social: {
                fbLikes: socialAPIs.social.facebook(result[0].facebook, function(totalCount) {
                  console.log('Facebook: ' + socialAPIs.social.formatNumber(totalCount));
                  return totalCount;
                }),
                instaFollowers: socialAPIs.social.instagram(result[0].instagram, function(totalCount) {
                  console.log('Instagram: ' + socialAPIs.social.formatNumber(totalCount));
                  return totalCount;
                }),
                twitterFollowers: socialAPIs.social.twitter(result[0].twitter, function(totalCount) {
                  console.log('Twitter: ' + socialAPIs.social.formatNumber(totalCount));
                  return totalCount;
                }),
                youtubeSubscribers: socialAPIs.social.youtube(result[0].youtube, function(totalCount) {
                  console.log('YouTube: ' + socialAPIs.social.formatNumber(totalCount));
                  return totalCount;
                })
              }
            };

            res.render('../spotlightMiddlePage/index.ejs', currentSpotlight);
          } else {
            res.send('The profile you\'re looking for does not exist.');
          }
        });
      }
    });

index.ejs

<%= social.fbLikes %>
          <%= social.instaFollowers %>
          <%= social.twitterFollowers %>
          <%= social.youtubeSubscribers %>

social.js

var rest = require('restler');
var FB = require('fb');
var ig = require('instagram-node').instagram();
var Twitter = require('twitter');
var twitterClient = new Twitter({
  consumer_key: 'i50oEcOL6eN6uCj7ToJEalmju',
  consumer_secret: 'vpxvAJf7UDebkF0ZcNKMe6Rrcr8bnDJymhJ0dmCuxL3Z46u93a',
  access_token_key: '1679587813-nRrhrV9zh1XUuPGRsgBrNZILBGAx6405eI5pPg4',
  access_token_secret: 'cO0mlOZtf7i7CjbwxPAaby0DmNl50GweTa9LWWFSbKB9o'
});

// --------------------------------------------------------------------------------------------------------------------------------------
// Facebook, Instagram, Twitter & YouTube
// --------------------------------------------------------------------------------------------------------------------------------------
exports.social = {
  facebook: function(url, callback) {
    FB.api(url + '?fields=fan_count&access_token=EAAEXeO7Hx60BABcJAzoL4mUS4VlRrTCUpl6KBGKu2f0XW3hkP683yZAjlHqkzA6ZBjymBlyAqmTd1c7qUlKkZC7jILMZB4VlVnixYZCSUJv2hTY7el04A5h4x0GrTXoao60XlDQ0ILje0Dh5x5AhHLyRalZCGjIC0ZD', function(res) {
      if (!res || res.error) {
        console.log(!res ? 'error occurred' : res.error);
        return;
      }

      var fan_count = res.fan_count;

      callback(fan_count);
    });
  },
  instagram: function(url, callback) {
    var userName = url.substring(26, url.length);

    rest.get('https://www.instagram.com/web/search/topsearch/?query={' + userName + '}').on('complete', function(result) {
      if (result instanceof Error) {
        console.log('Error:', result.message);
      } else {
        var followers_count = result.users[0].user.follower_count;

        callback(followers_count);
      }
    });
  },
  twitter: function(url, callback) {
    var screenName = url.substring(20, url.length);

    twitterClient.get('https://api.twitter.com/1.1/users/show.json?', {screen_name: screenName}, function(err, data) {
      if (!err) {
        var followers_count = data.followers_count;

        callback(followers_count);
      } else {
        console.log(err);
      }
    });
  },
  youtube: function(url, callback) {
    var channelId = url.substring(32, url.length);

    rest.get('https://www.googleapis.com/youtube/v3/channels?part=statistics&id=' + channelId + '&key=AIzaSyB3YdIk9nxLbTsRtNbVjmmX2a2ydksCBzI').on('complete', function(result) {
      if (result instanceof Error) {
        console.log('Error:', result.message);
      } else {
        var subscriber_count = result.items[0].statistics.subscriberCount;

        callback(subscriber_count);
      }
    });
  },
  formatNumber: function(number) {
    var ranges = [
      {divider: 1e9, suffix: 'B'},
      {divider: 1e6, suffix: 'M'},
      {divider: 1e3, suffix: 'K'}
    ];

    for (var i = 0; i < ranges.length; i++) {
      if (number >= ranges[i].divider) {
        return (Math.round(number / ranges[i].divider)).toString() + ranges[i].suffix;
      }
    }

    return number.toString();
  }
};
// --------------------------------------------------------------------------------------------------------------------------------------
// End Facebook, Instagram, Twitter & YouTube
// --------------------------------------------------------------------------------------------------------------------------------------

2 个答案:

答案 0 :(得分:1)

错误使用异步,结果永远不会应用于fbLikes或instaFollowers

例如,如果您尝试这样做:

// my async function
function b(callback){
   setTimeout(function(){
     console.log("done");
     return callback(2);
    }, 2000)
 }

 // call async function and applied result
  var a = b(function(r){
            return r;
       });

a将始终未定义,并且永远不会包含b调用的结果。 循环异步函数以设置结果然后渲染:

    currentSpotlight = {
      ...
      social: {
        "facebook" : 0,
        "twitter": 0,
        "youtube": 0,
        "instagram": 0
      }
   }

   var todo = Object.keys(currentSpotlight.social).length; // number of async fn to call
   var done = 0;

   // compute async fn
   for(var i in social)
   {
     let ci = i;
     socialAPIs.social[ci](result[0][ci], function(count){
        currentSpotlight.social[ci] = count;
        if(++done >= todo)
        {
            return res.render('../spotlightMiddlePage/index.ejs', currentSpotlight);
        }   
       })
    }

答案 1 :(得分:-1)

试试这个:

var html = new EJS({url:&#39; ../ spotlightMiddlePage / index.ejs&#39;})。render(currentSpotlight) res.render(HTML);