Get data based on form input Javascript - javascript

I have a form that takes user input and prints the data to a webpage. My goal is to connect to Twitter API and print data based on input result. For example, if the user inputs a certain hashtag, then I want all hashtags with the input data to be printed. I'm able to get input data and print it, I'm also able to print data from a hashtag on click (without input data). But when I'm trying to implement Twitter search with the input form, something is missing.
My form
<form class="form" action="/" method="post" name="form">
<input type="text" name="twdata" placeholder="Add data">
<button type="submit">Submit</button>
</form>
My js with Twitter API (not working)
var theTweets = [];
app.post('/',function(req,res){
// Grab form data and push it to array
var twdata = req.body.twdata;
var params = {
q: twdata
}
client.get('search/tweets', params, getData);
function getData(err, data, response) {
var content = data.statuses;
for (var i = 0; i < content.length; i++) {
theTweets.push( content[i].text );
}
}
// Display form data on home template
res.render('home', {twData: theTweets});
});
My js without Twitter API (working)
var formData = [];
app.post('/',function(req,res){
// Grab form data and push it to array
var twdata = req.body.twdata;
formData.push(twdata);
// Display form data on home template
res.render('home', {dataInfo: formData});
});
What am I doing wrong?

I think the main problem is due you are working with Node.js (Express) and you have to be aware of asynchronous invocation, this is a main problem when working with Node.js, we have to change our mind regarding the execution order since it is not procedural execution. I tried to simulate your program as a Node.js plain application, please check below:
var theTweets = [];
var res = {
render: function (page, objData) {
console.log(page +' '+objData.tweets);
}
}
var req = {
body: {
twdata: '#user'
}
}
var app = {
post: function (page, callback) {
console.log('Page invoked '+page);
callback(req, res);
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
var client = {
get : async function (tweets, params, callback) {
var err = '';
var data = {statuses: [{text:'tweet01'},{text:'tweet02'}]};
var response = {};
await sleep(2000); //code for simulate delay in async call to twitter
callback(err, data, response);
}
}
app.post('/', function(req, res) {
var twdata = req.body.twdata;
var params = {
q: twdata
}
client.get('search/tweets', params, getData);
function getData(err, data, response) {
var content = data.statuses;
content.forEach ((tweet)=>theTweets.push(tweet.text));
res.render('home', {'tweets': theTweets}); //correct
}
//res.render('home', {'tweets': theTweets}); //wrong
});

Related

sqlite- fetch data from multiple tables together- android and iOS

I have multiple sqlite tables and I want to fetch data from these tables together from Ionic 3 app for android and iOS platform and send it to server
Here's the code I wrote for this functionality
function fetchDataFromSqlite(){
let tableNames = ['table1','table2','table3'];
var dataFromSQLite= {};
for (var i = 0; i < tableNames.length; i++)
{
let tableName = tableNames[i];
let queryParams = [1];
let query = `SELECT * FROM ${tableName} WHERE status= ?`;
this.databaseprovider.SelectQry(query, queryParams).then(data => {
dataFromSQLite[tableName] = data;
});
return dataFromSQLite;
}
}
Above function is what I wrote to perform this action. I call this function in my app component
SelectQry() in databaseprovider looks like this:
SelectQry(sql, params) {
return this.database.executeSql(sql, params).then(
data => {
return data;
},
err => {
console.log("Error: ", JSON.stringify(err));
return [];
}
);
}
When I alert() the data returned from fetchDataFromSqlite() , I get {}
Can anyone tell me what I'm doing wrong or why I'm not getting any output when there's data in SQLite tables?

Node.js mssql return query result to ajax

I'm new to learning Node.js, so I'm still getting used to asynchronous programming and callbacks. I'm trying to insert a record into a MS SQL Server database and return the new row's ID to my view.
The mssql query is working correctly when printed to console.log. My problem is not knowing how to properly return the data.
Here is my mssql query - in addJob.js:
var config = require('../../db/config');
async function addJob(title) {
var sql = require('mssql');
const pool = new sql.ConnectionPool(config);
var conn = pool;
let sqlResult = '';
let jobID = '';
conn.connect().then(function () {
var req = new sql.Request(conn);
req.query(`INSERT INTO Jobs (Title, ActiveJD) VALUES ('${title}', 0) ; SELECT ##IDENTITY AS JobID`).then(function (result) {
jobID = result['recordset'][0]['JobID'];
conn.close();
//This prints the correct value
console.log('jobID: ' + jobID);
}).catch(function (err) {
console.log('Unable to add job: ' + err);
conn.close();
});
}).catch(function (err) {
console.log('Unable to connect to SQL: ' + err);
});
// This prints a blank
console.log('jobID second test: ' + jobID)
return jobID;
}
module.exports = addJob;
This is my front end where a modal box is taking in a string and passing it to the above query. I want it to then receive the query's returned value and redirect to another page.
// ADD NEW JOB
$("#navButton_new").on(ace.click_event, function() {
bootbox.prompt("New Job Title", function(result) {
if (result != null) {
var job = {};
job.title = result;
$.ajax({
type: 'POST',
data: JSON.stringify(job),
contentType: 'application/json',
url: 'jds/addJob',
success: function(data) {
// this just prints that data is an object. Is that because I'm returning a promise? How would I unpack that here?
console.log('in success:' + data);
// I want to use the returned value here for a page redirect
//window.location.href = "jds/edit/?jobID=" + data;
return false;
},
error: function(err){
console.log('Unable to add job: ' + err);
}
});
} else {
}
});
});
And finally here is the express router code calling the function:
const express = require('express');
//....
const app = express();
//....
app.post('/jds/addJob', function(req, res){
let dataJSON = JSON.stringify(req.body)
let parsedData = JSON.parse(dataJSON);
const addJob = require("../models/jds/addJob");
let statusResult = addJob(parsedData.title);
statusResult.then(result => {
res.send(req.body);
});
});
I've been reading up on promises and trying to figure out what needs to change here, but I'm having no luck. Can anyone provide any tips?
You need to actually return a value from your function for things to work. Due to having nested Promises you need a couple returns here. One of the core features of promises is if you return a Promise it participates in the calling Promise chain.
So change the following lines
jobID = result['recordset'][0]['JobID'];
to
return result['recordset'][0]['JobID']
and
req.query(`INSERT INTO Jobs (Title, ActiveJD) VALUES ('${title}', 0) ; SELECT ##IDENTITY AS JobID`).then(function (result) {
to
return req.query(`INSERT INTO Jobs (Title, ActiveJD) VALUES ('${title}', 0) ; SELECT ##IDENTITY AS JobID`).then(function (result) {
and
conn.connect().then(function () {
to
return conn.connect().then(function () {
You may need to move code around that is now after the return. You would also be well served moving conn.close() into a single .finally on the end of the connect chain.
I recommend writing a test that you can use to play around with things until you get it right.
const jobId = await addJob(...)
console.log(jobId)
Alternatively rewrite the code to use await instead of .then() calls.

How to return object to client when https request is fired in another file?

I'm trying to have the user be able to click a button, which sends a request to my node server and then with the data sent, it fires a function thats in another file. My problem isn't with the code, I'm just new to javascript so I'm not quite sure how i should be returning this object back to the client, i'm quite lost i'll explain more in the code below. I'm not sure if I should be doing something as simple as
return obj;
or If i should be using async/await, i've tried doing this but couldn't quite understand it.
http.createServer(function (req, res) {
res.setHeader('Content-Type', 'application/json');
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "X-Requested-With")
//res.writeHead(200, { 'Content-Type': 'text/plain' });
var data = []
if (req.method == "POST") {
res.writeHead(200, { 'Content-Type': 'text/plain' });
req.on('data', function (dat) {
data.push(dat)
})
req.on('end', function () {
var gamedata = Buffer.concat(data).toString();
var game = JSON.parse(gamedata)
games.getPing(game.placeId, 0)<--This is the function that gets fired in the other file
res.end(/*some how get games.gameservers here to send back to client*/)
})
}
}).listen(9999)
This is my node server that is in a file called server.js.
Now here is the function that gets fired. This function is in a file called api.js
games = {
gameservers: [],
getPing: function (id,index,callback) {
var keepAliveAgent = new https.Agent({ keepAlive: true })
var r = https.request(options, function (res) {
var data = []
res.on('data', function (d) {
data.push(d)
}).on('end', function () {
var buf = Buffer.concat(data)
var encodingheader = res.headers['content-encoding']
if (encodingheader == 'gzip') {
zlib.gunzip(buf, function (err, buffer) {
var o = JSON.parse(buffer.toString())
// o is what is returned
if (index < o.TotalCollectionSize) {
index = index + 10;
//console.log(index, o.TotalCollectionSize)
try {
let lowest = o.c.reduce((lowest, item) => item.x < lowest.x ? item : lowest)
if (lowest.q != lowest.p) {
// console.log(lowest)
games.gameservers.push(lowest)
}
games.getPing(id, index)
} catch (e) {
if (e) {
console.log(games.gameservers)
/*
This is where my function ends, I need to be able to send the games.gameservers array, back to the client in cloud.js
*/
}
}
}
})
}
})
})
r.end()
}
}
Inside the error of the try/catch, is where the function ends. Basically, the res.end() in server.js needs to have the games.gameservers object in it to go back to the client.
I'm pretty new to javascript as a whole, so i'm not sure if I should be using return, async/await, callbacks. I've been at this for awhile and cant seem to get it.
In Javascript, if you use function without "return" the function will return undefined. You can't do anything with that value.
Inside your method getPing. Use return to return your games.gameservers.
Inside your http.createServer . This part , you can write like this.
const result = [...games.getPing(game.placeId, 0)] (as you have return so this function will return your games.gameservers and assign it to result)
res.end(/some how get games.gameservers here to send back to client/)
Hope this help.

Node/Feathers with a database in the back

I am learning about Node and Feathers on a job. Need to make a simple app that would use feathers to load the [nedb] with sample data.
var fake = require('./fake.js');
var feathers = require('feathers-client');
var io = require('socket.io-client');
var socket = io("http://127.0.0.1:8000");
var app = feathers()
.configure(feathers.socketio(socket));
var accountsAPIService = app.service('/api/accounts');
var dummyData = fake();
// import dummy data
for ( var i = 0; i < dummyData.accounts.length; i++) {
// console.log(dummyData.accounts[i]);
var params = { query: {}};
accountsAPIService.create(dummyData.accounts[i], params).then(function(account) {
console.log("inserted: ", account);
});
}
// read back inserted records
accountsAPIService.find(params, function(accounts) {
console.log("accounts: ", accounts);
});
i just need to insert items from the array dummyData.accounts into the server.
When I run the script, it seems that nothing is being imported.
When I read the records back, it returns:
accounts: null
What is the proper way of inserting/creating records with Feathers?
Could not figure out how to use ".then" so used a regular form:
for ( var i = 0; i < dummyData.accounts.length; i++) {
var params = { query: {}};
accountsAPIService.create(dummyData.accounts[i], params, function(error, account) {
// console.log("inserted: ", account);
});
}
That works fine.
To read the data back, I corrected the method signature. Then, it works. :)
accountsAPIService.find(function(error, accounts) {
console.log("accounts: ", accounts);
});

Node/Express - How to wait until For Loop is over to respond with JSON

I have a function in my express app that makes multiple queries within a For Loop and I need to design a callback that responds with JSON when the loop is finished. But, I'm not sure how to do this in Node yet. Here is what I have so far, but it's not yet working...
exports.contacts_create = function(req, res) {
var contacts = req.body;
(function(res, contacts) {
for (var property in contacts) { // for each contact, save to db
if( !isNaN(property) ) {
contact = contacts[property];
var newContact = new Contact(contact);
newContact.user = req.user.id
newContact.save(function(err) {
if (err) { console.log(err) };
}); // .save
}; // if !isNAN
}; // for
self.response();
})(); // function
}; // contacts_create
exports.response = function(req, res, success) {
res.json('finished');
};
There are a few problems with your code besides just the callback structure.
var contacts = req.body;
(function(res, contacts) {
...
})(); // function
^ you are redefining contacts and res in the parameter list, but not passing in any arguments, so inside your function res and contacts will be undefined.
Also, not sure where your self variable is coming from, but maybe you defined that elsewhere.
As to the callback structure, you're looking for something like this (assuming contacts is an Array):
exports.contacts_create = function(req, res) {
var contacts = req.body;
var iterator = function (i) {
if (i >= contacts.length) {
res.json('finished'); // or call self.response() or whatever
return;
}
contact = contacts[i];
var newContact = new Contact(contact);
newContact.user = req.user.id
newContact.save(function(err) {
if (err)
console.log(err); //if this is really a failure, you should call response here and return
iterator(i + 1); //re-call this function with the next index
});
};
iterator(0); //start the async "for" loop
};
However, you may want to consider performing your database saves in parallel. Something like this:
var savesPending = contacts.length;
var saveCallback = function (i, err) {
if (err)
console.log('Saving contact ' + i + ' failed.');
if (--savesPending === 0)
res.json('finished');
};
for (var i in contacts) {
...
newContact.save(saveCallback.bind(null, i));
}
This way you don't have to wait for each save to complete before starting the next round-trip to the database.
If you're unfamiliar with why I used saveCallback.bind(null, i), it's basically so the callback can know which contact failed in the event of an error. See Function.prototype.bind if you need a reference.

Categories