Google Drive API JavaScript having trouble getting file properties - javascript

Hi I'm having trouble getting all images in the root folder in my Google Drive using the Google Drive API. I'm starting simple and getting some info from the first file I retrieve. When I get the ID I get 0By19fyuYeoHHN2M3LWRqRWNucWM, but I have tried other things such as title and thumbnailLink I get undefined. Only thing that seems to work is id and kind. I'm looking here for a list of properties of a file.
https://developers.google.com/drive/v2/reference/files
Not really sure what is wrong. My scope is 'https://www.googleapis.com/auth/drive'.
Thanks in advanced.
Code
function retrieveAllFilesInFolder(folderId, callback)
{
var retrievePageOfChildren = function(request, result)
{
request.execute(function(resp)
{
result = result.concat(resp.items);
var nextPageToken = resp.nextPageToken;
if (nextPageToken)
{
request = gapi.client.drive.children.list(
{
'folderId' : folderId,
'pageToken': nextPageToken
});
retrievePageOfChildren(request, result);
}
else
{
callback(result);
}
});
}
var initialRequest = gapi.client.drive.children.list(
{
'folderId' : folderId
});
retrievePageOfChildren(initialRequest, []);
}
function printToOutdiv(result)
{
document.getElementById("outdiv").innerHTML = result[0].id;
}
function GetFilesButton ()
{
gapi.client.load('drive', 'v2', function()
{
retrieveAllFilesInFolder('root',printToOutdiv);
});
}
Edit : Updated code and it works but you can't specify folder.
function retrieveAllFiles(callback)
{
var retrievePageOfFiles = function (request, result)
{
request.execute(function (resp)
{
result = result.concat(resp.items);
var nextPageToken = resp.nextPageToken;
if (nextPageToken)
{
request = gapi.client.drive.files.list(
{
'pageToken': nextPageToken
});
retrievePageOfFiles(request, result);
}
else
{
callback(result);
}
});
}
var initialRequest = gapi.client.drive.files.list();
retrievePageOfFiles(initialRequest, []);
}

Related

Unexpected Parsing Error On AWS Lambda JS

I think this is a syntax error but I'm having trouble finding documentation. I keep getting 'Parsing Error: Unexpected Token {". It says its to do with the 'YesIntent', but won't give specifics. I'm new to JS, but I can't see what could be the problem. Every '{' has a matching '}'.
Any insights would be appreciated. Thank you.
const Alexa = require("alexa-sdk");
const appId = ''; //'';
exports.handler = function(event, context, callback) {
const alexa = Alexa.handler(event, context);
alexa.appId = appId;
alexa.registerHandlers(handlers);
alexa.execute();
};
const handlers = {
'LaunchRequest': function() {
this.emit('YesIntent');
},
'YesIntent': function() {
getData(callback(title) {
this.response.speak('Here are your data ' + title);
this.emit(':responseReady');
}),
};
function getData() {
var ddb = new AWS.DynamoDB.DocumentClient({
region: 'us-west-1'
});
var params = {
TableName: 'WallyFlow_StartTime',
Key: 'TimeStamp',
};
ddb.get(params, function(err, data) {
if (err) {
callback(err, null);
} else {
title = data.Item.title;
}
});
}
Sorry, in this style you need more braces :) Updated to:
'YesIntent': function () {
getData( {
callback(title) {
this.response.speak('Here are your data ' + title);
this.emit(':responseReady');
}})
}};
I suspect it should be something like this. callback should be the name of the parameter to the getData() function, not something you call in the argument. The argument to getData() should be a function.
And getData() should call the callback function in the non-error case as well as the error case.
You also need an extra } to end the handlers object, and the end of the statement that calls getData() should be ;, not ,.
const handlers = {
'LaunchRequest': function() {
this.emit('YesIntent');
},
'YesIntent': function() {
getData(function(title) {
this.response.speak('Here are your data ' + title);
this.emit(':responseReady');
});
}
};
function getData(callback) {
var ddb = new AWS.DynamoDB.DocumentClient({
region: 'us-west-1'
});
var params = {
TableName: 'WallyFlow_StartTime',
Key: 'TimeStamp',
};
ddb.get(params, function(err, data) {
if (err) {
callback(err, null);
} else {
title = data.Item.title;
callback(title);
}
});
}

NodeJS make promise wait for completion of foreach loop

I have a NodeJS script that calls the API for users, gets multiple data for each user and writes it all to local file. I am trying to upload that file to server once all of the data is written into the file. The problem is that the code that should upload the file gets executed before the file is entirely populated. The code is written below. I can't figure out how to make promise wait for first function to complete.
var fs = require('fs');
var server = require('some-server');
var service = require('./some-service.js');
var moment = require('moment-timezone');
var csvWriter = require('csv-write-stream');
var writer = csvWriter({
sendHeaders: false
});
var users = require('./some-users')
writer.pipe(fs.createWriteStream('myFile' + '.txt'))
service.login().then(function (response) {
users.forEach(function (user) {
service.getSpecificUser(user).then(function (response) {
var myUser = JSON.parse(response)
service.getDataForUser(user.Info).then(function (response) {
var userData = JSON.parse(response);
if (userData.IsValid) {
userData.AdditionalInfo.forEach(function (additionalInfo) {
service.getAdditionalInfo(myUser.Info, userData.data).then(function (response) {
//Collect additional info and combine final results to write into file
// write to output csv file
writer.write({
//write information that is of interest
})
}, function (error) {
console.log('error getting additional data', error);
})
}
)
}
}, function (error) {
console.log('error getting user data', error)
})
}, function (error) {
console.log('error', myUser, error)
})
});
}, function (error) {
console.log('not logged', response);
}).then(function () {
//perform uploading to server
var fpath = 'path of file that contains downloaded data'
console.log("Trying to upload to file: " +fpath)
service.UploadFile(fpath, function (error, result, response) {
if (!error) {
console.log("Uploaded " + name);
}
else {
console.log(error);
}
})
})
Any help would be appreciated.
You can substitute Promise.all(), Array.prototytpe.map() for .forEach(). The documentation for csv-write-steam appears to use .end() to complete call .write() at last .then().
service.login().then(function(response) {
return Promise.all(users.map(function(user) {
return service.getSpecificUser(user).then(function(response) {
var myUser = JSON.parse(response)
return service.getDataForUser(user.Info).then(function(response) {
var userData = JSON.parse(response);
if (userData.IsValid) {
return Promise.all(userData.AdditionalInfo.map(function(additionalInfo) {
return service.getAdditionalInfo(myUser.Info, userData.data).then(function(response) {
//Collect additional info and combine final results to write into file
// write to output csv file
writer.write({
//write information that is of interest
});
})
}))
}
})
})
}));
})
.then(function() {
writer.end();
//perform uploading to server
var fpath = 'path of file that contains downloaded data'
console.log("Trying to upload to file: " + fpath)
service.UploadFile(fpath, function(error, result, response) {
if (!error) {
console.log("Uploaded " + name);
} else {
console.log(error);
}
})
})
.catch(function(e) {
console.log(e)
})

Make multiple callbacks from node js asynchronous function

How can I return a object of data returned by asynchronous function called multiple times from within a asynchronous function.
I'm trying to implement like this :
var figlet = require('figlet');
function art(dataToArt, callback)
{
var arry[];
figlet(dataToArt, function(err, data) {
if (err) {
console.log('Something went wrong...');
console.dir(err);
return callback('');
}
arry[0] = data;
callback(arry);
});
figlet(dataToArt, function(err, data) {
if (err) {
console.log('Something went wrong...');
console.dir(err);
return callback('');
}
arry[1] = data;
callback(arry);
});
}
art('Hello World', function (data){
console.log(data);
});
How can I do it correctly, I searched and searched but couldn't find a solution.
Ps. I'm using Figlet.js
I don't know if you're ok using an external module, but you can use tiptoe.
Install it using npm install tiptoe like any regular module and it basically goes like this:
var tiptoe = require('tiptoe')
function someAsyncFunction(obj, callback) {
// something something
callback(null, processedData);
}
tiptoe(
function() {
var self = this;
var arr = ['there', 'are', 'some', 'items', 'here'];
arr.forEach(function(item) {
someAsyncFunction(item, self.parallel());
});
},
function() {
var data = Array.prototype.slice.call(arguments);
doSomethingWithData(data, this);
},
function(err) {
if (err) throw (err);
console.log('all done.');
}
);
the someAsyncFunction() is the async function you want to call does something and calls the callback parameter as a function with the parameters error and data. The data parameter will get passed as an array item to the following function on the tiptoe flow.
Did it Myself :) Thanks to mostafa-samir's post
var figlet = require('figlet');
function WaterfallOver(list, iterator, callback) {
var nextItemIndex = 1;
function report() {
nextItemIndex++;
if(nextItemIndex === list.length)
callback();
else
iterator([list[0],list[nextItemIndex]], report);
}
iterator([list[0],list[1]], report);
}
var FinalResult = [];
WaterfallOver(["hello","Standard","Ghost"], function(path, report) {
figlet.text(path[0], { font: path[1] }, function(err, data) {
if (err) {
FinalResult.push("Font name error try help");
report();
return;
}
data = '<pre>.\n' + data + '</pre>';
FinalResult.push(data);
report();
});
}, function() {
console.log(FinalResult[0]);
console.log(FinalResult[1]);
});

Sequelize send picture from blob

Right now I create a new url based on rowid and stream the picture back using fs. Below is my code that works right now.
This saves the picture from the blob pulled from the database.
exports.picFileSave = function (name, data) {
try{
// Query the entry
stats = fs.lstatSync(name);
// Is it a directory?
if (stats.isFile()) {
//do nothing;
}
} catch (e) {
var wstream = fs.createWriteStream(name);
wstream.write(data);
wstream.end();
}
};
This function gets the picture filename and sends it back
exports.getLocBg = function (rowid, callback) {
var filename = "tmp/loc/" + rowid + ".png";
try{
// Query the entry
stats = fs.lstatSync(filename);
// Is it a directory?
if (stats.isFile()) {
callback(filename);
}
} catch (e) {
locationdb.location
.findOne({where: {id: rowid}})
.then(function (locations) {
var wstream = fs.createWriteStream(filename);
wstream.write(locations.locationBackground);
wstream.end();
callback(filename);
});
}
};
This is simply the route that connects the client to the server
app.get('/mobile/locations/locbg/:rowid', function (req, res) {
var options = {
root: "./",
dotfiles: 'deny',
headers: {
'x-timestamp': Date.now(),
'x-sent': true
}
};
var rowid = req.params.rowid;
location.getLocBg(rowid, function (callback) {
res.sendFile(callback, options, function (err) {
if (err) {
console.log(err);
res.status(err.status).end();
}
else {
console.log('Sent:', callback);
}
});
});
});
I want to be able to simply pull the blob from the database and send the picture back without writing a file and sending that back. How would I go about this?

Serialize function with PhantomJS bridge

I have an array of links that use link parametr for function that scraped data by PhantomJS.
How to serilize this function? This for statemant runs paralely 3 function in one time and i recive an event error.
In this case its proper to use async, but how it use in series? Time of running the functions are always different, but how async should understood that it's done and start with new URL?
var phantom = require('phantom')
, async = require('async');
var urls = [
'http://en.wikipedia.org/wiki/Main_Page',
'http://es.wikipedia.org/wiki/Wikipedia:Portada',
'http://de.wikipedia.org/wiki/Wikipedia:Hauptseite'
];
async.mapSeries(urls, getTitle, function(err, result){
console.log(result);
})
function getTitle (link, callback) {
phantom.create(function(ph) {
return ph.createPage(function(page) {
return page.open(link, function(status) {
return page.evaluate((function() {
return document.title;
}), function(result) {
callback(null, result);
return ph.exit();
});
});
});
});
};
I'd try something like:
var links = []
var _ph
function init(cb) {
phantom.create(function(ph) {
//for each link in links call doStuff()
_ph = ph
doStuff(ph, link, cb)
})
}
function doStuff(ph, link, cb) {
ph.createPage(function(page) { //does things in parallel?
page.open(link, function(status) {
page.evaluate((function() {
document.title;
}), function(result) {
cb(null, result);
page.close();
});
});
}
var counter = links.length
var titles;
function results(err, res) {
titles.push(res)
if(--counter == 0) {
//done
_ph.exit()
}
}
init(results)
Probably not working code (I wrote it here), but I hope you get the idea. If you want to only use 1 page, something like:
var links = []
var _ph
var _page
function init(cb) {
phantom.create(function(ph) {
_ph = ph
ph.createPage(function(page) {
_page = page
doStuff(link, cb)
}
})
}
function doStuff(page, link, cb) {
page.open(link, function(status) {
page.evaluate((function() {
document.title;
}), function(result) {
cb(null, result);
page.close();
});
});
}
var counter = links.length
var titles;
function results(err, res) {
titles.push(res)
if(--counter == 0) {
//done
_ph.exit()
return
}
doStuff(links[counter], results)
}
init(results)

Categories