I am trying to implement an autocompleter on a nodejs app using nowjs.
everyone.now.sendAutocomplete = function(search) {
var response = getAutocomplete(search);
console.log("response");
console.log(response);
};
which calls:
function getAutocomplete(search) {
console.log(search);
var artist = new Array();
request({uri: 'http://musicbrainz.org/ws/2/artist/?query=' + search + '&limit=4', headers: "Musicbrainz Application Version 1"}, function(error, response, body) {
par.parseString(body, function(err, result) {
var count = result['artist-list']['#']['count'];
var artists = result['artist-list']['artist'];
// var artist = new Array();
if (count > 1) {
artists.forEach(function(a) {
var att = a['#'];
var id = att['id'];
var name = a['name'];
var dis = a['disambiguation'];
if (dis) {
var display = name + " (" + dis + " )";
} else {
display = name;
}
artist.push({'id':id, 'name': name, 'disambiguation':dis,
'label':display, 'value':name, 'category':"Artists"});
});
//everyone.now.receiveResponse(artist);
console.log("artist");
console.log(artist);
return artist;
} else {
console.log(artists);
var att = artists['#'];
var id = att['id'];
var name = artists['name'];
var dis = artists['disambiguation'];
var resp = [{'id':id, 'name': name, 'disambiguation':dis,
'label':name, 'value':name, 'category':"Artists"}];
return resp;
// everyone.now.receiveResponse([{'id':id, 'name': name, 'disambiguation':dis,
// 'label':name, 'value':name, 'category':"Artists"}]);
}
});
});
}
However, console.log(response) says that response is undefined. I am new to node so the answer is probably simple, but still can't figure it out.
You are treating the async call as synchronous. Your getAutocomplete needs to take a callback function to get the response. You're using that a lot already, in your request call and your parseString call.
Like this:
everyone.now.sendAutocomplete = function(search) {
getAutocomplete(search, function (response) {
console.log("response");
console.log(response);
});
};
And instead of return:
function getAutocomplete(search, callback) {
// ...
callback(result);
// ...
}
Related
In Google Apps Script, I'm using some code I adapted from a project I found. It calls an API endpoint and lays out the data in a spreadsheet. I was able to get it to loop through multiple API calls in order to pull data from multiple documents. However, the code breaks if it finds a document with no data. In this case, I want it to just skip that iteration and start again at the next cardIds.forEach iteration.
Here's a link to a sample sheet.
I tried:
if (response == "") {
return;
}
But no dice. Here's the full code (also it's very inefficient. I have params on their twice because I'm not sure how to consolidate them with all the functions inside other functions..)
const DATA_SHEET = "Data";
const USERNAME_CELL = "B1";
const API_TOKEN_CELL = "B2";
const CARD_ID_COL = "Cards!B:B"
const DATA_RANGE = "A4:C"
var getNextPage = function(response) {
var url = response.getAllHeaders().Link;
if (!url) {
return "";
}
return /<([^>]+)/.exec(url)[1];
};
var getIt = function(path, username, apiToken) {
var params = {
"method": "GET",
"muteHttpExceptions": true,
"headers": {
"Content-Type": "application/json",
"Authorization": "Basic " + Utilities.base64Encode(username + ":" + apiToken),
"x-guru-application": "spreadsheet",
"X-Amzn-Trace-Id": "GApp=spreadsheet"
}
};
var response = UrlFetchApp.fetch(path, params);
var data = JSON.parse(response.getContentText());
// check if there's another page of results.
var nextPage = getNextPage(response);
if (nextPage) {
data.nextPage = nextPage;
};
return data;
};
var getItAll = function(url, username, apiToken, callback) {
var data = [];
while (url) {
var page = getIt(url, username, apiToken);
var startIndex = data.length;
page.forEach(function(a) {
data.push(a);
});
// get the url of the next page of results.
url = page.nextPage;
if (callback) {
// the second parameter is whether we're done or not.
// if there's a url for the next page that means we're not done yet.
callback(data, startIndex, page.length, url ? false : true);
}
}
return data;
};
function eachCard() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(DATA_SHEET);
sheet.getRange(DATA_RANGE).clearContent();
var username = sheet.getRange(USERNAME_CELL).getValue();
var apiToken = sheet.getRange(API_TOKEN_CELL).getValue();
var cardIds = sheet.getRange(CARD_ID_COL).getValues().flat().filter(r=>r!="");
var params = {
"method": "GET",
"muteHttpExceptions": true,
"headers": {
"Content-Type": "application/json",
"Authorization": "Basic " + Utilities.base64Encode(username + ":" + apiToken),
"x-guru-application": "spreadsheet",
"X-Amzn-Trace-Id": "GApp=spreadsheet"
}
};
cardIds.forEach(function (cardId) {
var fullUrl = "https://api.getguru.com/api/v1/cards/"+cardId+"/comments"
var cardComments = getItAll(fullUrl, username, apiToken);
var fullUrl = "https://api.getguru.com/api/v1/cards/"+cardId+"/extended"
var response = UrlFetchApp.fetch(fullUrl, params);
var cardData = JSON.parse(response.getContentText());
var sheetLastRow = sheet.getLastRow();
var range = sheet.getRange("A" + sheetLastRow);
if (range.getValue() !== "") {
var lastRow = sheetLastRow+1;
} else {
var lastRow = range.getNextDataCell(SpreadsheetApp.Direction.UP).getRow()+1;
}
cardComments.forEach(function(comment, commentIndex) {
sheet.getRange(lastRow + commentIndex, 1).setValue(comment.dateCreated);
sheet.getRange(lastRow + commentIndex, 1 + 1).setValue(comment.content);
sheet.getRange(lastRow + commentIndex, 1 + 2).setValue(cardData.preferredPhrase);
});
});
}
I have just started learning to code about 5 days ago and what I'm struggling to achieve, is to have an rssfeed-to-twitter script that posts a shortened url instead of a full website/article feed url. I found a node.js module called TinyURL that could do that but i struggle to get it to work. Here's the full script:
var simpleTwitter = require('simple-twitter');
var fs = require('fs');
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type' : 'text/plain'});
res.end('RSS Twitter Bot\n');
}).listen(5693);
var timeInterval = 300000; // run every 30m
var timerVar = setInterval (function () {runBot()}, timeInterval);
function runBot(){
var lastCompleted = Date.parse(new Date(0));
console.log(lastCompleted);
try {
var lastcompletedData = fs.readFileSync('./lastCompleted.json', 'utf8');
var timeData = JSON.parse(lastcompletedData);
var lastCompletedFromFile = Date.parse(new Date(timeData.lastCompleted));
if ( isNaN(lastCompletedFromFile) == false ) {
lastCompleted = lastCompletedFromFile;
}
} catch (e) {
console.log(e);
}
fs.readFile('./config.json', 'utf8', function (err, data) {
if (err) console.log(err); // we'll not consider error handling for now
var configData = JSON.parse(data);
console.log(configData);
var twitter = new simpleTwitter( configData.consumerKey //consumer key from twitter api
, configData.consumerSecret //consumer secret key from twitter api
, configData.accessToken //access token from twitter api
, configData.accessTokenSecret //access token secret from twitter api
, 3600);
var dateNow = Date.parse(new Date());
var FeedParser = require('feedparser');
var request = require('request');
var req = request(configData.feedUrl);
var feedparser = new FeedParser();
req.on('error', function (error) {
console.log(error);
});
req.on('response', function (res){
var stream = this;
if (res.statusCode != 200 ) return this.emit('error', new Error('Bad status code'));
stream.pipe(feedparser);
});
feedparser.on('error', function(error) {
console.log(error);
});
feedparser.on('readable', function() {
var stream = this;
var meta = this.meta;
var item;
while (item = stream.read()) {
var itemDate = Date.parse(item.date);
//check to not publish older articles
if (itemDate > lastCompleted){
var titleLength = item.title.length;
var itemTitle = item.title;
var itemLink = item.link;
if (titleLength > 100) {
itemTitle = itemTitle.substring(0, 100);
}
twitter.post('statuses/update'
, {'status' : itemTitle + ' ' + itemLink + " " + configData.tags}
, function (error, data) {
console.dir(data);
});
console.log(itemTitle + ' ' + item.link + configData.tags);
}
}
//TO KNOW WHEN FROM TO START POSTING
var dateCompleted = new Date();
console.log('loop completed at ' + dateCompleted);
var outputData = {
lastCompleted : dateCompleted
}
var outputFilename = './lastCompleted.json';
fs.writeFile(outputFilename, JSON.stringify(outputData, null, 4), function(err) {
if(err) {
console.log(err);
} else {
console.log("JSON saved to " + outputFilename);
}
});
});
});
}
And this is the TinyURL node.js module
var TinyURL = require('tinyurl');
TinyURL.shorten('http://google.com', function(res) {
console.log(res); //Returns a tinyurl
});
Changing the 'http://google.com' string to itemLink var works just fine and prints it in the terminal as expected.
TinyURL.shorten(itemLink, function(res) {
console.log(res); //Returns a tinyurl
});
What i'm trying to achieve is:
twitter.post('statuses/update', {'status' : itemTitle + ' ' + tinyurlLink + " " + configData.tags}
How can i get the response turned into a e.g var tinyurlLink to replace the itemLink var? Any help would be much appreciated!
As suggested by #zerkms sending a tweet from inside the TinyURL.shorten worked!
Trying to create a lambda function that lists tagged ec2 and tagged rds and performs an action thereafter. This is the first time i have used javascript and would appreciate some help.
Please see my example below
var aws = require('aws-sdk');
var ec2 = new aws.EC2();
var rds = new aws.RDS();
aws.config.region = 'us-east-1';
exports.handler = function(event,context) {
if (event) {
console.log(event.id);
}
//setup params for rds call
var rdsparams = {
DBInstanceIdentifier: 'master',
};
//setup params for ec2 call
var ec2params = {
Filters: [
{
Name: 'tag:role',
Values: [
'app'
],
}
]
};
//Get ec2 instances with app tag, may need to add a condition on running so pulled it into hash
ec2.describeInstances(ec2params, function(err, appdata) {
if (err) {
console.log(err);
return;
}
else {
var apparray={};
for(var i = 0; i < appdata.Reservations.length; i++) {
var ins = appdata.Reservations[i].Instances[0];
var id = ins.InstanceId;
var state = ins.State.Name;
apparray[id]=state;
}
console.log(apparray);
context.succeed(apparray);
}
});
rds.describeDBInstances(rdsparams, function(err, data) {
if (err) {
console.log(err, err.stack);
return;
}
else {
var rdsarray={};
var rdsarray=(data);
console.log(rdsarray);
var ins=rdsarray[0];
var name = ins.ReadReplicaDBInstanceIdentifiers[0];
rdsarray[replicant]=name;
}
context.succeed(rdsarray);
});
//context.done();
};
I want to return my filtered (apparray) and (rdsarray) back from my functions and perform a calculation on this within the main body of the script. Any ideas on how to do this.
something like
var replicas = rdsarray.length for example
Thanks in advance
var aws = require('aws-sdk');
var ec2 = new aws.EC2();
var rds = new aws.RDS();
aws.config.region = 'us-east-1';
exports.handler = function(event, context) {
if (event) {
console.log(event.id);
}
//setup params for rds call
var rdsparams = {
DBInstanceIdentifier: 'master',
};
//setup params for ec2 call
var ec2params = {
Filters: [{
Name: 'tag:role',
Values: [
'app'
],
}]
};
//Get ec2 instances with app tag, may need to add a condition on running so pulled it into hash
ec2.describeInstances(ec2params, function(err, appdata) {
if (err)
return context.done(err, null);
var apparray = {};
for (var i = 0; i < appdata.Reservations.length; i++) {
var ins = appdata.Reservations[i].Instances[0];
var id = ins.InstanceId;
var state = ins.State.Name;
apparray[id] = state;
}
console.log(apparray);
var resultData = {};
resultData.apparray = apparray;
rds.describeDBInstances(rdsparams, function(err, data) {
if (err)
return context.done(err, null);
var rdsarray = {};
var rdsarray = (data);
console.log(rdsarray);
var ins = rdsarray[0];
var name = ins.ReadReplicaDBInstanceIdentifiers[0];
rdsarray[replicant] = name;
resultData.rdsarray = rdsarray;
context.done(null, resultData);
});
});
};
and back in the code from you are calling the lambda function
var lambda = new sdk.Lambda();
var params = {
FunctionName: 'arn:aws:lambda:us-west-2:1541546477777:function:MyFunction',
Payload: JSON.stringify(/*your params here*/)
};
lambda.invoke(params, function(err, data) {
if (err) {
console.log('error ===', err);
return ;
}
var lambdaData = JSON.parse(data.Payload);
// do your stuff here
});
Is this what you needed? It may be broken but I hope you get the idea of it
I am trying to retrieve a json object to use it in another module, but I have a problem with callback. I have the error "callback is not a function". I use callback because my variable description is undefined, so i guess it's a problem of asynchronous.
Could you help me plz :)
var leboncoin = function () {
var http = require('http')
var bl = require('bl')
http.get("http://www.website.com", function (response, callback) {
response.pipe(bl(function (err, data) {
if (err) {
return console.error(err)
callback(err);
}
var data = data.toString()
var brand = ...
var model = ...
var releaseDate = ...
var km = ...
var fuel = ...
var gearbox = ...
description.Brand = brand;
description.Model = model;
description.Year = releaseDate;
description.KM = km;
description.Fuel = fuel;
description.Gearbox = gearbox;
callback(description);
return (description)
/*console.log(description.Brand);
console.log(description.Model);
console.log(description.Year);
console.log(description.KM);
console.log(description.Fuel);
console.log(description.Gearbox);*/
}))
})
}
exports.leboncoin = leboncoin;
var module = require('./leboncoin');
var res = module.leboncoin();
console.log(res);
Callbacks aren't magic that just appear. You need to define a parameter to your function and pass the callback you want to use.
// --------------------------v
var leboncoin = function (callback) {
var http = require('http')
var bl = require('bl')
http.get("http://www.website.com", function (response) {
response.pipe(bl(function (err, data) {
if (err) {
callback(err);
return;
}
var data = data.toString()
var description = { /* your description object */ }
callback(description);
}))
})
}
exports.leboncoin = leboncoin;
var module = require('./leboncoin');
// -----------------vvvvvvvv
module.leboncoin(function(res) {
console.log(res);
});
The method http.get requires a function that accepts only a parameter named response (or whatever you want, the name doesn't matter indeed), thus your second one, callback, is undefined and invoking it will end ever in that error.
Im having a problem with my mobile app i do not know how to solve it.
when i push a button that gets data from a database, i parse it in json and when i want to use it in my app i get the undefined. Hoe can i make it so i do not get the undifined.
Note
I only get the undefind when the database is empty.
This is the code that i use
subjectButton.addEventListener('click', function(e) {
Subjects.getSubjects(url, function(response) {
if(response == '') {
alert('There where no subjects found');
} else {
subjectView.remove(subjectsLabel);
var data = JSON.parse(response);
if(data != 'undefined') {
var subjectNameButton = [];
var subjectEditButton = [];
var subjectDeleteButton = [];
for(i in data) {
id = data[i].id;
var subject = data[i].subject;
var year = data[i].year;
var status = data[i].status;
var color;
Ti.API.info('id: ' + id);
Ti.API.info('type id: '+ typeof id);
Can someone explain to me how i can make it so i don't get the undefined
Like #0101 said json can't return undefined so your problem is somewhere else.
I know this is not the best solution but it seems to work for me:
subjectButton.addEventListener('click', function(e) {
Subjects.getSubjects(url, function(response) {
if(response == '') {
alert('There where no subjects found');
} else {
subjectView.remove(subjectsLabel);
var data = JSON.parse(response);
var subjectNameButton = [];
var subjectEditButton = [];
var subjectDeleteButton = [];
for(i in data) {
id = data[i].id;
var subject = data[i].subject;
var year = data[i].year;
var status = data[i].status;
var color;
Ti.API.info('id: ' + id);
if(id != undefined) {
//Your code here
} else {
alert('There where no subjects found');
}
}
}
});
});
So here you have a check if one of the variables returns undefined or not. If it isn't undefined it will run your code else it will give you / the user an alert message
You will never get "undefined" from JSON.parse. The error must occurred somewhere else. Try this:
Subjects.getSubjects(url, function(response) {
if(!response) {
alert('There where no subjects found');
}
else {
subjectView.remove(subjectsLabel); // You probably should move this after JSON.parse
try {
var data = JSON.parse(response),
subjectNameButton = [],
subjectEditButton = [],
subjectDeleteButton = [];
for (i in data) { // Global i?
id = data[i].id; // Global too?
var subject = data[i].subject;
var year = data[i].year;
var status = data[i].status;
var color;
Ti.API.info('id: ' + id);
Ti.API.info('type id: '+ typeof id);
// ...
}
}
catch(e) {
console.log("Invalid JSON")
};
// ...
}
}