Keen.io JS api responding {"code": "UnknownError"} when event created OK - javascript

I'm trying to create a Keen event from parse.com cloud code (node.js). I'm using a JS module (https://github.com/roycef/keen-parse) which seems to be set up OK. To test things, I've set up a simple test and here is the complete main.js (credentials removed):
var express = require('express');
var app = express();
// Global app configuration section
app.use(express.bodyParser());
var Keen = require('cloud/keen.js');
var keen = Keen.configure({
projectId: "xxxxxxxx",
writeKey: "xxxxxxxx"
});
app.get('/kiss', function (req, res) {
var resp = {};
var respCode = 404;
var testObj = {"firstname": "John", "surname": "Doe"};
// send single event to Keen IO
keen.addEvent("Testola", testObj, function (err, res) {
if (err) {
resp = err;
respCode = 500;
} else {
resp = res.data;
respCode = 200;
}
}).then(function () {
// send something back to the app
res.setHeader('Content-Type', 'application/json');
res.send(resp, respCode);
});
});
app.listen();
When I GET /kiss:
the record is stored in the relevant collection at Keen.io (yay - I can see it in the Expolorer!) however
the response received (err) is {"code": "UnknownError"}
So, 2 questions:
why is the error response being sent when the event seems to be recorded correctly at keen.io?
what can I do to get the above working?

It looks like keen-parse is using the old node-specific SDK for Keen. That SDK was deprecated quite a while ago, and I believe there have been some breaking changes in the API since then.
You probably want to use keen-js directly, instead. It's super simple to set up, and I don't think you really lose any functionality from keen-parse.

Give keen-tracking.js a try. This is a new tracking-only SDK that is a full drop-in replacement for keen-js. Here is a quick rewrite of your example code w/ the new SDK in place:
var express = require('express');
var app = express();
// Global app configuration section
app.use(express.bodyParser());
var Keen = require('keen-tracking');
var keen = new Keen({
projectId: "xxxxxxxx",
writeKey: "xxxxxxxx"
});
app.get('/kiss', function (req, res) {
var resp = {};
var respCode = 404;
var testObj = {"firstname": "John", "surname": "Doe"};
// send single event to Keen IO
keen.recordEvent("Testola", testObj, function (err, res) {
res.setHeader('Content-Type', 'application/json');
if (err) {
res.send(err, 500);
}
else {
res.send(res, 200);
}
});
});
app.listen();

Related

How to query from flutter to node js

Hello i have small problem here but i don't know how to solve it
I have a data from flutter "townid" what i want is to query using node.js from flutter's post request
//code from flutter app
Future getB(townId) async{
var data;
print(townId);
final response = await http.post("http://xxx.xxx.xx.xx:3000/selectB",body:{
"townid": townId.toString()
});
data = jsonDecode(response.body);
return data;
}
//my node js that receive my flutter request
const express = require('express');
const bodyParser = require("body-parser");
const mysql = require('mysql');
const router = express.Router();
const db = require('./db');
const app = express();
app.use(bodyParser);
router.post('/selectB', function (req, res) {
var townid = req.query; // i dont know if this is the correct way to do this
db.connect(function(err) {
//Select all customers and return the result object:
db.query("SELECT `town_id` as `tid` , `brgy_name` as `brg_name` FROM barangays WHERE `town_id` = $townid ", function (err, result, fields) { // i don't know if this is the correct way to do this
if (err) throw err;
res.send(result);
});
});
})
From the node side, you'll have to fetch the townid as :
var townid = req.body.townid
//node
var townid = req.body['townid']
try this maybe this might work
since the body of post request from your flutter app is
body:{"townid": townId.toString()});
you can parse the boy using body-parser and this is what it looks like
const townid = req.body.townid

Getting cannot POST / error in Express

I have a RESTful API that I am using postman to make a call to my route /websites. Whenever I make the call, postman says "Cannot POST /websites". I am trying to implement a job queue and I'm using Express, Kue(Redis) and MongoDB.
Here is my routes file:
'use strict';
module.exports = function(app) {
// Create a new website
const websites = require('./controllers/website.controller.js');
app.post('/websites', function(req, res) {
const content = req.body;
websites.create(content, (err) => {
if (err) {
return res.json({
error: err,
success: false,
message: 'Could not create content',
});
} else {
return res.json({
error: null,
success: true,
message: 'Created a website!', content
});
}
})
});
}
Here is the server file:
const express = require('express');
const bodyParser = require('body-parser');
const kue = require('kue');
const websites = require('./app/routes/website.routes.js')
kue.app.listen(3000);
var app = express();
const redis = require('redis');
const client = redis.createClient();
client.on('connect', () =>{
console.log('Redis connection established');
})
app.use('/websites', websites);
I've never used Express and I have no idea what is going on here. Any amount of help would be great!!
Thank you!
The problem is how you are using the app.use and the app.post. You have.
app.use('/websites', websites);
And inside websites you have:
app.post('/websites', function....
So to reach that code you need to make a post to localhost:3000/websites/websites. What you need to do is simply remove the /websites from your routes.
//to reach here post to localhost:3000/websites
app.post('/' , function(req, res) {
});

NodeJS multi site web scrape

I am learning NodeJS and trying to scrape a fan wikia to get names of characters and store them in a json file. I have an array of character names and I want to loop through them and scrape each character name from each url in the array. The issue I am running into is:
throw new Error('Can\'t set headers after they are sent.');
Here is my source code at the moment:
var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app = express();
app.get('/', function(req, res){
var bosses = ["Boss1","Boss2"];
for (boss in bosses) {
url = 'http://wikiasiteexample.com/' + bosses[boss];
request(url, function (error, response, html) {
if (!error) {
var $ = cheerio.load(html);
var title;
var json = { title: "" };
$('.page-header__title').filter(function () {
var data = $(this);
title = data.text();
json.title = title;
})
}
fs.writeFile('output.json', JSON.stringify(json, null, 4), {'flag':'a'}, function(err) {
if (err) {
return console.error(err);
}
});
res.send('Check your console!')
})
}
})
app.listen('8081')
console.log('Running on port 8081');
exports = module.exports = app;
You're calling res.send() for every request you make.
Your HTTP request can only have one response, so that gives an error.
You must call res.send() exactly once.
Promises (and Promise.all()) will help you do that.

Node.js app giving ERR_EMPTY_RESPONSE

I'm having serious issues with an app I am building with Node.js, Express, MongoDB and Mongoose. Last night everything seemed to work when I used nodemon server.js to `run the server. On the command line everything seems to be working but on the browser (in particular Chrome) I get the following error: No data received ERR_EMPTY_RESPONSE. I've tried other Node projects on my machine and they too are struggling to work. I did a npm update last night in order to update my modules because of another error I was getting from MongoDB/Mongoose { [Error: Cannot find module '../build/Release/bson'] code: 'MODULE_NOT_FOUND'}. I used the solution in this answer to try and fix it and it didn't work and I still get that error. Now I don't get any files at all being served to my browser. My code is below. Please help:
//grab express and Mongoose
var express = require('express');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//create an express app
var app = express();
app.use(express.static('/public/css', {"root": __dirname}));
//create a database
mongoose.connect('mongodb://localhost/__dirname');
//connect to the data store on the set up the database
var db = mongoose.connection;
//Create a model which connects to the schema and entries collection in the __dirname database
var Entry = mongoose.model("Entry", new Schema({date: 'date', link: 'string'}), "entries");
mongoose.connection.on("open", function() {
console.log("mongodb is connected!");
});
//start the server on the port 8080
app.listen(8080);
//The routes
//The route for getting data for the database
app.get("/database", function(req, res) {
Entry.find({}, function(err, data) {console.log(err, data, data.length); });
});
//The route for posting data on the database
app.post("/database", function(req, res) {
//test new post
var newMonth = new Entry({date: '1997-10-30', link: 'https://wwww.youtube.com/'});
newMonth.save(function(err) {
if (err !== null) {
//object was not save
console.log(err);
} else {
console.log("it was saved!")
};
});
});
//create an express route for the home page at http://localhost:8080/
app.get('/', function(req, res) {
res.send('ok');
res.sendFile('/views/index.html', {"root": __dirname + ''});
});
//Send a message to the console
console.log('The server has started');
//The route for getting data for the database
app.get("/database", function(req, res) {
Entry.find({}, function(err, data) {console.log(err, data, data.length); });
});
//The route for posting data on the database
app.post("/database", function(req, res) {
//test new post
var newMonth = new Entry({date: '1997-10-30', link: 'https://wwww.youtube.com/'});
newMonth.save(function(err) {
if (err !== null) {
//object was not save
console.log(err);
} else {
console.log("it was saved!")
};
});
});
These routes don't send anything back to the client via res. The bson error isn't a big deal - it's just telling you it can't use the C++ bson parser and instead is using the native JS one.
A fix could be:
//The route for getting data for the database
app.get("/database", function(req, res) {
Entry.find({}, function(err, data) {
if (err) {
res.status(404).json({"error":"not found","err":err});
return;
}
res.json(data);
});
});
//The route for posting data on the database
app.post("/database", function(req, res) {
//test new post
var newMonth = new Entry({date: '1997-10-30', link: 'https://wwww.youtube.com/'});
newMonth.save(function(err) {
if (err !== null) {
res.status(500).json({ error: "save failed", err: err});
return;
} else {
res.status(201).json(newMonth);
};
});
});
updated june 2020
ERR_EMPTY_RESPONSE express js
package.json
"cors": "^2.8.4",
"csurf": "^1.9.0",
"express": "^4.15.4",
this error show when you try to access with the wrong HTTP request. check first your request was correct
maybe your cors parameter wrong

flatiron.js routing and templating with union, director and plates?

Coming from express.js, I want to give flatiron a try for a small project. However, there are some small problems which keep me from actually getting somewhere.
var flatiron = require('flatiron')
, session = require('connect').session
, ecstatic = require('ecstatic')
, path = require('path')
, fs = require('fs')
, plates = require('plates')
, director = require('director')
, winston = require('winston')
, union = require('union');
var router = new director.http.Router();
var server = union.createServer({
before: [
ecstatic(__dirname + '/public')
]
});
router.get('/', function () {
var self = this;
fs.readFile('public/layout.html', 'utf-8', function(err, html) {
[...]
})
});
server.listen(3000, function () {
console.log('Application is now started on port 3000');
});
How does routing with director work? When I leave ecstatic out, I can define routes like '/' and it works, but then I don't get static CSS and JS content. With ecstatic / is replaced with 'index.html' and ecstatic has priority over all defined routes.
- It's the same behavior with connect-static. Route (/) is replaced by index.html.
I also tried a different approach using the connect middleware, which doesn't work:
var flatiron = require('flatiron')
, connect = require('connect')
, path = require('path')
, fs = require('fs')
, plates = require('plates')
, app = flatiron.app;
app.use(flatiron.plugins.http);
app.use(connect.favicon());
app.use(connect.static(__dirname + '/public'));
app.use(connect.directory(__dirname + '/public'));
app.use(connect.cookieParser('my secret here'));
app.use(connect.session({'secret': 'keyboard cat'}));
app.router.get('/', function () {
console.log("GET /");
var self = this;
fs.readFile('public/layout.html', 'utf-8', function(err, html) {
[...]
})
});
app.listen(3000, function () {
console.log('Application is now started on port 3000');
});
I think the best answer for your question about routing in flatiron is, as always, inside the source code:
app.server = union.createServer({
after: app.http.after,
before: app.http.before.concat(function (req, res) {
if (!app.router.dispatch(req, res, app.http.onError || union.errorHandler)) {
if (!app.http.onError) res.emit('next');
}
}),
headers: app.http.headers,
limit: app.http.limit
});
As you can see here flatiron binds router as the last request handler, that is called after all middleware. If you place 'ecstatic' in app.http.before and it will be dispatched during workflow, no other middleware would be called.
Your second block of code demonstrates that you don't undestand difference between Flatiron's .use() method from Express/Connect's. I'll try to make it clear on this example:
flatironApp.use({
// plugin object
name : "pluginName"
, attach : function(options) {
/*code*/
}
, init : function(done) {
/*code*/
done();
}
})
connectApp.use(function(req, res, next) {
/* code */
next();
})
If you want to use Connect's middleware in Flatiron you should place it respectively in app.http.before array like this:
// Initiating application
app.use(flatiron.plugins.http);
// Adding request handlers
app.http.before.push( connect.favicon() );
app.http.before.push( ecstatic(__dirname + '/public') );
var connect = require('connect');
var server = union.createServer({
before: [
function (req, res) {
var found = router.dispatch(req, res);
if (!found) {
res.emit('next');
}
},
connect.static('public')
]
});
I forgot to insert the dispatch-function. This works.

Categories