Azure: Cannot call method 'then' of undefined at exports.post - javascript

I am using azure mobile services, with following custom API:
var returnVal = new Object;
exports.post = function (request, response) {
// Use "request.service" to access features of your mobile service, e.g.:
// var tables = request.service.tables;
// var push = request.service.push;
var merchantdetailsTable = request.service.tables.getTable("merchantdetails");
var resourceName;
//console.log(JSON.stringify(request.parameters));
merchantdetailsTable.insert({
name: request.body.workerNameInput,
emailid: request.body.workerEmailIDInput,
contact: request.body.workerContactNumberInput
}).then(function (merchantInserted) {
returnVal.workerId = merchantInserted.id;
resourceName = returnVal.workerId.toLowerCase();
var shopworkersTable = request.service.tables.getTable("shopworkers");
return shopworkersTable.insert({
id: merchantInserted.id,
shopid: request.body.shopId
});
}, function(err){
return response.send(statusCodes.INTERNAL_SERVER_ERROR, err);
}).then(function () {
var accountName = appSettings.STORAGE_ACCOUNT_NAME;
var accountKey = appSettings.STORAGE_ACCOUNT_ACCESS_KEY;
var host = accountName + '.blob.core.windows.net';
var blobService = azure.createBlobService(accountName, accountKey, host);
return blobService.createContainerIfNotExists("merchant-image", { publicAccessLevel: 'blob' });
}, function (err) {
return response.send(statusCodes.INTERNAL_SERVER_ERROR, err);
}).then(function(error){
if (!error) {
// Provide write access to the container for the next 5 mins.
var sharedAccessPolicy = {
AccessPolicy: {
Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.WRITE,
Expiry: new Date(new Date().getTime() + 5 * 60 * 1000)
}
};
// Generate the upload URL with SAS for the new image.
var sasQueryUrl =
blobService.generateSharedAccessSignature("merchant-image",
'', sharedAccessPolicy);
// Set the query string.
returnVal["merchantImage"].sasQueryString = qs.stringify(sasQueryUrl.queryString);
// Set the full path on the new new item,
// which is used for data binding on the client.
returnVal["merchantImage"].imageUri = sasQueryUrl.baseUrl + sasQueryUrl.path + '/'
+ resourceName;
var accountName = appSettings.STORAGE_ACCOUNT_NAME;
var accountKey = appSettings.STORAGE_ACCOUNT_ACCESS_KEY;
var host = accountName + '.blob.core.windows.net';
var blobService = azure.createBlobService(accountName, accountKey, host);
return blobService.createContainerIfNotExists("pharmacy-certificate", { publicAccessLevel: 'blob' });
}
else {
return response.send(statusCodes.INTERNAL_SERVER_ERROR);
}
}, function (err) {
return response.send(statusCodes.INTERNAL_SERVER_ERROR, err);
}).done(function (error) {
if (!error) {
// Provide write access to the container for the next 5 mins.
var sharedAccessPolicy = {
AccessPolicy: {
Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.WRITE,
Expiry: new Date(new Date().getTime() + 5 * 60 * 1000)
}
};
// Generate the upload URL with SAS for the new image.
var sasQueryUrl =
blobService.generateSharedAccessSignature("pharmacy-certificate",
'', sharedAccessPolicy);
// Set the query string.
returnVal["pharmacyCertificate"].sasQueryString = qs.stringify(sasQueryUrl.queryString);
// Set the full path on the new new item,
// which is used for data binding on the client.
returnVal["pharmacyCertificate"].imageUri = sasQueryUrl.baseUrl + sasQueryUrl.path + '/'
+ resourceName;
response.send(statusCodes.OK, returnVal);
}
else {
return response.send(statusCodes.INTERNAL_SERVER_ERROR);
}
}, function (err) {
return response.send(statusCodes.INTERNAL_SERVER_ERROR, err);
});
response.send(statusCodes.OK, { message : 'Hello World!' });
};
exports.get = function(request, response) {
response.send(statusCodes.OK, { message : 'Hello World!' });
};
I am getting following error:
TypeError: Cannot call method 'then' of undefined
at exports.post (D:\home\site\wwwroot\App_Data\config\scripts\api\addWorker.js:17:8)

Azure Mobile Services does not return promises from table operations. You need to pass an options object that contains success and error callbacks, as described at https://msdn.microsoft.com/en-us/library/azure/jj554210.aspx.
I highly recommend that you take a look at the newer implementation of the product, Azure Mobile Apps - https://www.npmjs.com/package/azure-mobile-apps. (Disclaimer: I work for Microsoft on the Azure Mobile Apps team)

Related

Using Oauth token created in JS in .Net client for getting google calendar events

I'm using the JS Quick Start example
I have Inserted that example in a .Net Framework 4.7 Web App in the Index View.
I modified the listUpcomingEvents as follows
function listUpcomingEvents() {
let data = {
"email" : gapi.auth2.getAuthInstance().currentUser.I4.value.Du.tv,
"token" : gapi.client.getToken().access_token
}
fetch('http://localhost:53658/api/Default/', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'userData': JSON.stringify(data)
}
})
.then(response => {
if (response.ok) { // if HTTP-status is 200-299
// get the response body (the method explained below)
response.text().then(myAnswer => {
console.log(myAnswer);
})
} else {
console.error.log("HTTP-Error: " + response.status);
}
});
gapi.client.calendar.events.list({
'calendarId': 'primary',
'timeMin': (new Date()).toISOString(),
'showDeleted': false,
'singleEvents': true,
'maxResults': 10,
'orderBy': 'startTime'
}).then(function(response) {
var events = response.result.items;
appendPre('Upcoming events:');
if (events.length > 0) {
for (i = 0; i < events.length; i++) {
var event = events[i];
var when = event.start.dateTime;
if (!when) {
when = event.start.date;
}
appendPre(event.summary + ' (' + when + ')')
}
} else {
appendPre('No upcoming events found.');
}
});
}
This is the code I have in the DefaultController/Get
const string ApplicationName = "Google Calendar API .NET Quickstart";
const string clientId = "------";
const string clientSecret = "-----";
// GET: api/Default
public string Get()
{
var re = Request;
var headers = re.Headers;
var jsonString = "";
if (headers.Contains("userData"))
{
jsonString = headers.GetValues("userData").First();
}
gUserData? userData = JsonConvert.DeserializeObject<gUserData>(jsonString);
// Create Google Calendar API service.
var flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = clientId,
ClientSecret = clientSecret
},
Scopes = new[] { CalendarService.Scope.Calendar,
CalendarService.Scope.CalendarReadonly}
});
var credential = new UserCredential(flow, userData.email, new TokenResponse
{
AccessToken = userData.token
});
// Create Google Calendar API service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
EventsResource.ListRequest request2 = service.Events.List("primary");
request2.TimeMin = DateTime.Now;
request2.ShowDeleted = false;
request2.SingleEvents = true;
request2.MaxResults = 10;
request2.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime;
// List events.
Events events = request2.Execute();
string sEvents = JsonConvert.SerializeObject(events.Items);
return sEvents;
}
All seems to be working... but when Events events = request2.Execute(); is executed I get the next error:
System.InvalidOperationException: 'The access token has expired and could not be refreshed. Errors: refresh error, refresh error, refresh error'
Any Ideas?
The requirement is: the user must log in in the frontend, get the OAuth token, use it in the backend to save the data

Post - Cannot GET error - Local server

I am trying to create an API using a local server for testing. The route
'GET' works fine, however 'POST' has a problem and it is returning 'Cannot GET /add/name'. I am developing the API using node.js and Express. Why am I receiving get when the route is set to 'POST'? Where is the problem?
var fs = require('fs');
var data = fs.readFileSync('events.json');
var allEvents = JSON.parse(data);
console.log(allEvents);
console.log('Server running.');
var express = require('express');
var app = express();
var sever = app.listen(3000, listening);
function listening() {
console.log('Serving...');
}
app.use(express.static('website'));
//GET and send all data from JSON
app.get('/all', sendAll);
function sendAll(request, response) {
response.send(allEvents);
}
//POST new data to JSON
app.post('/add/:name', addData);
function addData(request, response) {
var newData = request.params;
var name = newData.name;
var eventType = newData.eventType;
var reply;
// var newEvent = {
// name: ":name",
// eventType: ":eventType",
// };
var newData = JSON.stringify(allEvents, null, 2);
fs.writeFile('events.json', newData, finished);
function finished(err) {
console.log('Writting');
console.log(err);
var reply = {
word: word,
score: score,
status: 'Success'
}
response.send(reply);
}
}
Request
$(function() {
//HTML
var $list = $('#list');
var jsonURL = '../events.json'
$.ajax({
type: 'GET',
url: '/all',
success: function(data) {
console.log('Data received', data);
$.each(data, function (type, string) {
$list.append('<li>' + type + " : " + string + '</li>');
});
},
error: function (err) {
console.log('Error, data not sent.', err);
}
});
$('#submit').on('click', function () {
// var newEvent = {
// name: $name.val(),
// eventType: $eventType.val(),
// };
var name = $('#fieldName').val();
var eventType = $('#fieldEventType').val();
console.log(name);
$.ajax({
type: 'PUT',
url: '/add/' + name,
success: function (addData) {
$list.append('<li>name: ' + name + '</li>');
},
error: function (err) {
console.log('Error saving order', err);
}
});
});
});
Thank you in advance.
For testing POST request, you can use Postman to test it. If you use the browser to call the api, it will be GET method instead of POST.

return resolve error in node function

Why wont usernametoid function return the acual id? cause im trying to send the result of the userdata as the return. In this case, i want to only send the userdata`s _id attribute. but it seems like it wont work.
console.log(userdata._id); // works
return resolve(userdata._id); // wont work.
output of variable userdata:
{
cash: 7300002,
bank: 0,
xp: 0,
rank: 1,
points: 1,
location: 1,
health: 100,
protection: 1,
attack: 1,
family: '0',
password: 'jKa4qC7pRCgE5jvzD9Vv1pRUNxFlQEM7Jpq/IoJ/sUWOAv1Wx1RI/j/Vu6Zf8zyNkCFcg3QBtdfAC+lmPS8KIA==',
profileImageURL: 'modules/users/client/img/profile/default.png',
roles: [ 'user' ],
created: Sat Aug 27 2016 12:33:55 GMT-0400 (EDT),
__v: 0,
username: 'signature',
provider: 'local',
salt: '4ySlrr9ggESxBB3dR5bx4Q==',
_id: 57c1c0f3b6b20c011242bf22 }
when i do: `return resolve(userdata._id) it would get this error:
/server/factory/user_factory.js:52
return resolve(userdata._id);
^
TypeError: Cannot read property '_id' of null
node.js call:
var articles = require('../controllers/articles.server.controller'),
path = require('path'),
mongoose = require('mongoose'),
Article = mongoose.model('Article'),
Users = mongoose.model('User'),
errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller'));
var userFunc = require('../factory/user_factory.js');
app.post('/api/kill', function (req, res) {
console.log("starting");
var username = "signature";//req.query.username;
var result = ["test service"];
var data = req.user;
userFunc.usernametoid(username).then( function (otherplayerid) {
if (!(otherplayerid)) {
console.log("other player is acually " + otherplayerid);
result.push("denne brukeren finnes ikke! " + otherplayerid);
} else {
userFunc.usernametoid(otherplayerid).then( function (otherplayer) {
if (data.location != otherplayer.location) {
result.push("Du er ikke i samme lokasjon som " + username);
result.push(data.location + " vs " + otherplayer.location);
} else {
userFunc.addCash(req.user._id,100000);
result.push("starter lokasjonisering");
}
});
}
res.json(result);
});
});
user factory:
var articles = require('../controllers/articles.server.controller'),
path = require('path'),
mongoose = require('mongoose'),
Article = mongoose.model('Article'),
Users = mongoose.model('User'),
errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller'));
exports.usernametoid = usernametoid;
function usernametoid(id) {
return new Promise( function (resolve, reject) {
var query = Users.findOne( { username : id } );
// var query = Users.find({_id:id});
query.exec(function(err, userdata) {
if (err){
return reject({err : 'Error while getting user info'});
}
console.log(userdata._id);
return resolve(userdata);
});
}, function (){
return reject({err : 'error while fetching cash'});
});
}
Because you are not passing correctly the fetched user to the query.exec.
You need to do:
var Users = require('../models/users-model.js');
function usernametoid(id) {
return new Promise( function (resolve, reject) {
Users.findOne({ username : id }).then( function(user){
//If you use lodash you can do _.isNull(user)
if(user == null){
return reject({error : 'User not found'});
}
user.exec(function(userdata, error) {
if(userdata){
return resolve(userdata);
}
if(error){
return reject({error : 'Error while executing query'});
}
});
});
});
}
I don't really get why you are importing Users Model like that. I do not think Node will be able to fetch it like that.
And, you should require mongoose in your server.js
To catch the rejection you need the following code:
UserFactory.userNameToId(id).then( function(response){
if(response.error){
console.log('error '+response.error);
}
if(response){
console.log('Got response '+response);
}
});

How to make wordpress.com login connect work with meteor

I'm following these tutorial:
https://developer.wordpress.com/docs/oauth2/
https://developer.wordpress.com/docs/wpcc/
https://github.com/Automattic/wpcom-connect-examples/blob/master/express.js/app.js
So I setup Meteor.loginWithWordpresscom with the following code:
Accounts.oauth.registerService('wordpresscom');
if (Meteor.isClient) {
Meteor.loginWithWordpresscom = function(options, callback) {
// support a callback without options
if (! callback && typeof options === "function") {
callback = options;
options = null;
}
var credentialRequestCompleteCallback = Accounts.oauth.credentialRequestCompleteHandler(callback);
Wordpresscom.requestCredential(options, credentialRequestCompleteCallback);
};
} else {
Accounts.addAutopublishFields({
forLoggedInUser: ['services.wordpresscom'],
forOtherUsers: ['services.wordpresscom.username']
});
}
And then I request credential with the following code:
Wordpresscom = {};
Wordpresscom.requestCredential = function (options, credentialRequestCompleteCallback) {
if (!credentialRequestCompleteCallback && typeof options === 'function') {
credentialRequestCompleteCallback = options;
options = {};
}
var config = ServiceConfiguration.configurations.findOne({service: 'wordpresscom'});
if (!config) {
credentialRequestCompleteCallback && credentialRequestCompleteCallback(
new ServiceConfiguration.ConfigError());
return;
}
var credentialToken = Random.secret();
var loginStyle = OAuth._loginStyle('wordpresscom', config, options);
var loginUrl =
'https://public-api.wordpress.com/oauth2/authorize' +
'?client_id=' + config.clientId +
'&redirect_uri=http://localhost:3000/connected' +
'&response_type=token' +
'&grant_type=authorization_code' +
'&scope=global'
OAuth.launchLogin({
loginService: "wordpresscom",
loginStyle: loginStyle,
loginUrl: loginUrl,
credentialRequestCompleteCallback: credentialRequestCompleteCallback,
credentialToken: credentialToken,
popupOptions: {width: 900, height: 450}
});
};
At the server, I request accessToken and identity with following code:
Wordpresscom = {};
OAuth.registerService('wordpresscom', 2, null, function(query) {
var accessToken = getAccessToken(query);
var identity = getIdentity(accessToken);
return {
serviceData: {
id: identity.ID,
accessToken: OAuth.sealSecret(accessToken),
email: identity.email,
username: identity.username,
displayName: identity.display_name,
avatar: identity.avatar_URL
},
options: {profile: {
name: identity.display_name,
displayName: identity.display_name,
avatar: identity.avatar_URL
}}
};
});
var getAccessToken = function (query) {
var config = ServiceConfiguration.configurations.findOne({service: 'wordpresscom'});
if (!config)
throw new ServiceConfiguration.ConfigError();
var response;
try {
response = HTTP.post(
"https://public-api.wordpress.com/oauth2/token", {
params: {
code: query.code,
client_id: config.clientId,
client_secret: OAuth.openSecret(config.secret),
redirect_uri: 'http://localhost:3000/connected',
grant_type: 'authorization_code'
}
});
} catch (err) {
throw _.extend(new Error("Failed to complete OAuth handshake with WordPress.com. " + err.message),
{response: err.response});
}
if (response.data.error) { // if the http response was a json object with an error attribute
throw new Error("Failed to complete OAuth handshake with WordPress.com. " + response.data.error);
} else {
console.log('getAccessToken');
return response.data.access_token;
}
};
var getIdentity = function (accessToken) {
console.log('getIdentity');
try {
return HTTP.get(
"https://public-api.wordpress.com/rest/v1/me", {
headers: {
/*"User-Agent": userAgent,*/
"Authorization": 'Bearer ' + accessToken
},
params: {access_token: accessToken}
}).data;
} catch (err) {
throw _.extend(new Error("Failed to fetch identity from WordPress.com. " + err.message),
{response: err.response});
}
};
Wordpresscom.retrieveCredential = function(credentialToken, credentialSecret) {
return OAuth.retrieveCredential(credentialToken, credentialSecret);
};
When I fire Meteor.loginWithWordpresscom popup window show up to ask user whether to approve or deny my app with this link http://localhost:3000/connected?code=a8kiRGwRPC
I get code a8kiRGwRPC to request access_token
After I approve, it redirect to http://localhost:3000/connected#access_token=w%5EQ7CFcvZQx3t%28OjspIs84v13BsbyUGROzrYh3%23aiLJQ%25NB%2AZ7jMjNX2%29m7%23t5J4&expires_in=1209600&token_type=bearer&site_id=0
Just like that. No new user stored in Meteor.users database
Any help would be appreciated
Thanks

Nodejs exports.module How to export Variable to other Script

my goal is to get a list of files from a google drive folder and its subfolders as json string. so i can then use express to expose it as an API endpoint that other applications can connect to it.
the code is working. i get everything i want, but i do not know how to export my data variable to app.js
// get-filelist.js
var GoogleTokenProvider = require("refresh-token").GoogleTokenProvider,
request = require('request'),
async = require('async'),
data
const CLIENT_ID = "514...p24.apps.googleusercontent.com";
const CLIENT_SECRET = "VQs...VgF";
const REFRESH_TOKEN = "1/Fr...MdQ"; // get it from: https://developers.google.com/oauthplayground/
const FOLDER_ID = '0Bw...RXM';
async.waterfall([
//-----------------------------
// Obtain a new access token
//-----------------------------
function(callback) {
var tokenProvider = new GoogleTokenProvider({
'refresh_token': REFRESH_TOKEN,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET
});
tokenProvider.getToken(callback);
},
//-----------------------------
// connect to google drive, look for the folder (FOLDER_ID) and list its content inclusive files inside subfolders.
// return a list of those files with its Title, Description, and view Url.
//-----------------------------
function(accessToken, callback) {
// access token is here
console.log(accessToken);
// function for token to connect to google api
var googleapis = require('./lib/googleapis.js');
var auth = new googleapis.OAuth2Client();
auth.setCredentials({
access_token: accessToken
});
googleapis.discover('drive', 'v2').execute(function(err, client) {
getFiles()
function getFiles(callback) {
retrieveAllFilesInFolder(FOLDER_ID, 'root' ,getFilesInfo);
}
function retrieveAllFilesInFolder(folderId, folderName, callback) {
var retrievePageOfChildren = function (request, result) {
request.execute(function (err, resp) {
result = result.concat(resp.items);
var nextPageToken = resp.nextPageToken;
if (nextPageToken) {
request = client.drive.children.list({
'folderId': folderId,
'pageToken': nextPageToken
}).withAuthClient(auth);
retrievePageOfChildren(request, result);
} else {
callback(result, folderName);
}
});
}
var initialRequest = client.drive.children.list({
'folderId': folderId
}).withAuthClient(auth);
retrievePageOfChildren(initialRequest, []);
}
function getFilesInfo(result, folderName) {
result.forEach(function (object) {
request = client.drive.files.get({
'fileId': object.id
}).withAuthClient(auth);
request.execute(function (err, resp) {
// if it's a folder lets get it's contents
if(resp.mimeType === "application/vnd.google-apps.folder"){
retrieveAllFilesInFolder(resp.id, resp.title, getFilesInfo);
}else{
/*if(!resp.hasOwnProperty(folderName)){
console.log(resp.mimeType);
}*/
url = "http://drive.google.com/uc?export=view&id="+ resp.id;
html = '<img src="' + url+ '"/>';
// here do stuff to get it to json
data = JSON.stringify({ title : resp.title, description : resp.description, url : url});
//console.log(data);
//console.log(resp.title);console.log(resp.description);console.log(url);
//.....
}
});
});
}
});
}
]);
// export the file list as json string to expose as an API endpoint
console.log('my data: ' + data);
exports.files = function() { return data; };
and in my app.js i use this
// app.js
var jsonData = require('./get-filelist');
console.log('output: ' + jsonData.files());
the data variable in app.js doesnt contain any data, while checking the output inside the function getFilesInfo() is working.
so, how to make my data variable accessible in other scripts?
You've got a problem with sync/async behavior.
app.js should be aware when to call the files() function exported from get-filelist. The code you've got there calls the files() function immediately after requiring the get-filelist module. At that moment the data variable is still empty.
Best solution would be to provide the files() function with a callback that will trigger once you've loaded the data variable.
Of course, you will need some extras:
the loaded flag so that you know whether to trigger the callback immediately (if data is already loaded) or postpone the trigger once the load is done.
the array for waiting callbacks that will be triggered upon load (callbacks).
// get-filelist.js
var GoogleTokenProvider = require("refresh-token").GoogleTokenProvider,
request = require('request'),
async = require('async'),
loaded = false, //loaded? Initially false
callbacks = [], //callbacks waiting for load to finish
data = [];
const CLIENT_ID = "514...p24.apps.googleusercontent.com";
const CLIENT_SECRET = "VQs...VgF";
const REFRESH_TOKEN = "1/Fr...MdQ"; // get it from: https://developers.google.com/oauthplayground/
const FOLDER_ID = '0Bw...RXM';
async.waterfall([
//-----------------------------
// Obtain a new access token
//-----------------------------
function(callback) {
var tokenProvider = new GoogleTokenProvider({
'refresh_token': REFRESH_TOKEN,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET
});
tokenProvider.getToken(callback);
},
//-----------------------------
// connect to google drive, look for the folder (FOLDER_ID) and list its content inclusive files inside subfolders.
// return a list of those files with its Title, Description, and view Url.
//-----------------------------
function(accessToken, callback) {
// access token is here
console.log(accessToken);
// function for token to connect to google api
var googleapis = require('./lib/googleapis.js');
var auth = new googleapis.OAuth2Client();
auth.setCredentials({
access_token: accessToken
});
googleapis.discover('drive', 'v2').execute(function(err, client) {
getFiles()
function getFiles(callback) {
retrieveAllFilesInFolder(FOLDER_ID, 'root' ,getFilesInfo);
}
function retrieveAllFilesInFolder(folderId, folderName, callback) {
var retrievePageOfChildren = function (request, result) {
request.execute(function (err, resp) {
result = result.concat(resp.items);
var nextPageToken = resp.nextPageToken;
if (nextPageToken) {
request = client.drive.children.list({
'folderId': folderId,
'pageToken': nextPageToken
}).withAuthClient(auth);
retrievePageOfChildren(request, result);
} else {
callback(result, folderName);
}
});
}
var initialRequest = client.drive.children.list({
'folderId': folderId
}).withAuthClient(auth);
retrievePageOfChildren(initialRequest, []);
}
function getFilesInfo(result, folderName) {
data = []; //data is actually an array
result.forEach(function (object) {
request = client.drive.files.get({
'fileId': object.id
}).withAuthClient(auth);
request.execute(function (err, resp) {
// if it's a folder lets get it's contents
if(resp.mimeType === "application/vnd.google-apps.folder"){
retrieveAllFilesInFolder(resp.id, resp.title, getFilesInfo);
}else{
/*if(!resp.hasOwnProperty(folderName)){
console.log(resp.mimeType);
}*/
url = "http://drive.google.com/uc?export=view&id="+ resp.id;
html = '<img src="' + url+ '"/>';
// here do stuff to get it to json
data.push(JSON.stringify({ title : resp.title, description : resp.description, url : url}));
//console.log(resp.title);console.log(resp.description);console.log(url);
//.....
}
});
});
//console.log(data); //now, that the array is full
//loaded is true
loaded = true;
//trigger all the waiting callbacks
while(callbacks.length){
callbacks.shift()(data);
}
}
});
}
]);
// export the file list as json string to expose as an API endpoint
console.log('my data: ' + data);
exports.files = function(callback) {
if(loaded){
callback(data);
return;
}
callbacks.push(callback);
};
Now the app.js behavior needs to change:
// app.js
var jsonData = require('./get-filelist');
jsonData.files(function(data){
console.log('output: ' + data);
});
/* a much more elegant way:
jsonData.files(console.log.bind(console,'output:'));
//which is actually equivalent to
jsonData.files(function(data){
console.log('output: ',data); //without the string concatenation
});
*/

Categories

Resources