2016-11-29 59 views
0

在app.js中,隨時可以在社交對象中查看console.log totalcount,我可以在終端中看到正確的值。但是當我嘗試在index.ejs中查看這些值時,它們都是未定義的。爲什麼是這樣?無法將node.js中的方法的正確值返回到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 
// -------------------------------------------------------------------------------------------------------------------------------------- 
+0

你不能返回值,查找異步的JavaScript。 – magreenberg

回答

-1

試試這個:

VAR HTML =新EJS({網址: 」 ../spotlightMiddlePage/index.ejs'}).render(curre ntSpotlight) res.render(html);

+0

該代碼適用於EJS的不同實現。 – RyanZim

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; 
     }); 

一個將永遠不確定的,絕不會包含的結果的電話。 遍歷異步函數來設置的結果,那麼渲染:

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); 
     } 
     }) 
    }