Getting HTML instead of JSON from NodeJs - javascript

I am working on project containing app and landing pages. We are using Nodejs with Axios and VueJs for app part. But for landing pages, it is simple jQuery. I must do some API calls for landing pages, but I am not able to use NodeJs result in jQuery to serve data in my landing pages. I am new at NodeJs and these technologies.
Here are my codes:
my Routes :
const router = express.Router();
...
router.get('/api/items', myApiController.getItems);
NodeJs controller
module.exports.getItems = (req, res) => {
const response = myApiController.getItems();
if (response.status === 200) {
res.send({
status: 200,
data: response.data
})
} else {
res.send({
status: 404,
data: null
})
}
}
my main script :
$.get("/api/items", function(data, status){
alert("Data: " + data);
var mylist = $("#mylist");
$.each(data, function(item) {
mylist.append($("<option />").val(item.name).text(item.name));
});
});
Even if I am getting status:200 the nodejs is returning HTML of page 404.
I do not find the cause, And honestly I do not understand the reason. It seems it is try to get a page does not exist, but I am requesting a json from function.
I try to replace contoller method call by a trash json but nothing work.
Here is what I try:
router.get('/api/items', function(req, res){
console.log('cc');
return res.json([{
'toto': 'toto',
'tata': 'tata',
}]);
});
It seems routes definitions issue, but I do not know how to fix. Could this have something with express Router ? Could you please explain me and help me to fix this? Thanks

When you respond with a string, the content type will be HTML. Try this, which removes the res.json call:
router.get('/api/items', function(req, res){
console.log('cc');
return [{
'toto': 'toto',
'tata': 'tata',
}];
});

Related

getting request data from getInitialProps()

I am trying to post data from a python script to a Next js server.
#python script
import requests
post_data = {'username':'bob', 'id' : 32}
# POST some form-encoded data:
post_response = requests.post(url='http://localhost:3000/foo', data=post_data)
I do get a request on a server, but I do not know how to retrieve the data in getInitalProps(). I have looked at the documentation but there seems to be no such information.
static async getInitialProps({props, req})
{
console.log('request data: ', req.data);
}
Crashed into the very same problem and found the solution well hidden in the Next.JS forums.
In short, first you need the Urlencoded Body Parser library to help parse the HTTP request object. Using npm to install it:
npm install --save urlencoded-body-parser
Then in your code file, you call its function to get an object with the post variables in it:
import parse from 'urlencoded-body-parser';
static async getInitialProps(context)
{
if (context.req.method === "POST") {
const data = await parse(context.req);
console.log("request data: ", data);
}
}
Results, based on question sample data:
{
"username": "bob",
"id" : "32"
}
It should be like this:
static getInitialProps ({ query: { data } }) {
console.log('request data: ', data);
}
please not that you also need to pass the data in server.js:
server.get('/foo', (req, res) => {
return app.render(req, res, '/pageFoo', req.query)
})

Why am I failing to get data from the server using angularjs $http.get()?

The question should be clear enough, and my code should display the issue. Any questions just comment underneath.
app.js
var express = require('express');
var app = express();
app.use(express.static('public'));
var characters = {"Griffins":
[{"Name":"Lois Griffin",
"Gender":"Female",
"Role": "Mother"},
{"Name":"Chris Griffin",
"Gender":"Male",
"Role": "Son"},
{"Name":"Meg Griffin",
"Gender":"Female",
"Role": "Daughter"}]
};
app.get("/characters", function(req, res) {
res.send(characters);
})
app.listen(9000, function(){
console.log('Running');
});
angular.js
app.controller('listCtrl',function($scope, $http){
$scope.characterData = function() {
$http.get("/characters").then(function(data) {
console.log(data, 'success')
},function(data) {
console.log("data, failure.")
})
}
})
error
Failed to load resource: the server responded with a status of 404 (
Object "failure."
object in error
Object -
config : Object
data : "Cannot GET /characters↵"
headers : function (d)
status : 404
statusText : "Not Found"
__proto__ : Object
Note: When using $http.get('characters.json')... I am able to get the data from a file called 'character.json'.
404 is a code which the server sends, when the server is not able to find a resource. There can be many reasons that lead to a 404 in response but the most common one's are:
wrong path given.
spelling problem in the path.
$http.get(url, [config]) : There are 2 arguments that are accepted. url is a absolute/relative path. This is a reason why, $http.get('characters.json') is working instead of $http.get('/characters').
So, you should instead use the proper path. If, 'characters.json' is inside '\characters' directory, you should give the correct path $http.get('\characters\characters.json') so that the server can locate the file.
And also, since you are sending json data, you should use, res.json instead of res.send.
The get method in angular need the full url string, probably is something like this:
app.controller('listCtrl',function($scope, $http){
var serverHost = 'example.com';
var serverPort = '9000';
$scope.characterData = function() {
$http.get("http://'+serverHost+':'+serverPort+'/characters").then(function(data) {
console.log("success");
console.log(data);
},function(data) {
console.log("failure");
console.log(data);
})
}
});
Make characters.json file and change app.get method in app.js
app.get('/characters', function (req, res) {
// First read existing users.
fs.readFile( __dirname + "/" + "characters.json", 'utf8', function (err, data) {
data = JSON.parse( data );
console.log( data );
res.end( JSON.stringify(data ));
});
})
//change your server configuration
var server = app.listen(8089, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
You can get Json Data in your html page
My own problem now seems to be working. I don't know what is going on, I think there are stability issues in using an online work space and a virtual machine to run servers, even though there shouldn't be. Thank you for everybody's input, I still managed to pick up some good information.

Add an error page to this express app?

I'm building an express app, a basic twitter interface.
I want to add an error page to the application, so that if anything goes wrong with the routes the user will see a friendly message rendered, instead of the default error code.
Here is a snippet of my code:
//Tell app to render template
app.get('/', function(req, res){
if(!error){
res.render('index', {
myName: myName,
profileImage: profileImage,
screenName: screenName,
followerCount: followerCount,
dateTweeted: dateTweeted,
tweetContent: tweetContent,
noOfRetweets: noOfRetweets,
noOfLikes: noOfLikes,
});
}
});
Why can't I just do this?
else{
res.send('sorry, bro, page not found!);
}
Or do I need to do something with passing the error to the 'next’ handler? I can't get my head around how that works.
Would really appreciate some help please!
Your question is not very specific but I assume you will get some errors during manipulation.
Then you can send type of error like this after getting error
//Tell app to render template
app.get('/', function(req, res) {
if ("not error") {
//You can do whatever you want
res.status(200).send({message:"Success message"})
}else{//If error you can choose your error code with relevant message
res.status(400).send({message:"Bad request error"});
//OR
res.status(404).send({message:"Not found error"});
//OR
res.status(401).send({message:"Unauthorization error"});
//OR
res.send(500).send({message:"Any server side erorr"});
}
});
You can build a custom middlewarethat does this for you...
function errorMiddleware(req, res, next) {
// implement some logic, do your check...
let thereAreErrors = /* ? */ false;
if(!thereAreErrors) {
return next();
}
return res.status(400).end();
}
function indexRouteCtrl(req, res) {
return res.render('index');
}
app.get('/'/, errorMiddleware, indexRouteCtrl);

How to write result in a file by using node.js and express?

I've built an application using node.js and express.js on top of elasticsearch. This is very simple application with a search box. When you search for a query, it prints result in JSON format. For eg, if I search for keyword "white", the output looks like this: http://i.stack.imgur.com/VHuWl.png
Now I want to store this result in a file(for eg output.json).This is my json file:
var fs = require('fs');
var path = "output.json";
var express = require('express'); //To make use of Express' routing capabilities you need to initiate a new Express Router.
var router = express.Router(); //To make use of Express' routing capabilities you need to initiate a new Express Router. get, put, post, delete, all
var searchModule = require('../search_module/search.js');
//There are two ways of using the router methods. You can define one route (for example /home) and attach the methods to it, or you can create a new method for each route.
/* GET home page. */
router.get('/', function(req, res) { //.get() - when you visit a website you make a GET request. You can get data from a URL in a GET request too.
res.render('index', { title: 'Express' });
});
router.post('/search-results', function(req, res) {//.post() is a method used everywhere for posting data to a server / app. You'll want to use this for submitting forms.
searchModule.search(req.body, function(data) {
res.render('index', { title: 'Express', results: data });
});
});
fs.writeFile(path,data,function(err){
if(err) console.error(err);
})
module.exports = router;
When I tried using writeFile method of node.js, I am getting an Reference error showing that "data" is not defined. My error looks like this: http://i.stack.imgur.com/lwXfW.png
I am not able to figure out this error. Is there any other way to write the output to a file by using node.js and express?
Edit: I edited my javascript
var fs = require('fs');
var path = "output.json";
var express = require('express'); //To make use of Express' routing capabilities you need to initiate a new Express Router.
var router = express.Router(); //To make use of Express' routing capabilities you need to initiate a new Express Router. get, put, post, delete, all
var searchModule = require('../search_module/search.js');
//There are two ways of using the router methods. You can define one route (for example /home) and attach the methods to it, or you can create a new method for each route.
/* GET home page. */
router.get('/', function(req, res) { //.get() - when you visit a website you make a GET request. You can get data from a URL in a GET request too.
res.render('index', { title: 'Express' });
});
router.post('/search-results', function(req, res) {//.post() is a method used everywhere for posting data to a server / app. You'll want to use this for submitting forms.
searchModule.search(req.body, function(data) {
fs.writeFile(path,data,function(err){
if(err) console.error(err);
})
res.render('index', { title: 'Express', results: data });
});
});
module.exports = router;
But when I ran this javascript, I got this output:
http://i.stack.imgur.com/rfBq0.png
I am not getting the JSON output. My output should look like this: http://i.stack.imgur.com/VHuWl.png
I am also using an ejs file with my javascript for the frontend(index.ejs) which looks like this:
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<h1><%= title %></h1>
<form action='/search-results' method='post'>
<input type="text" name="searchTerm" placeholder="your search term here">
<button type="submit"> SEARCH </button>
</form>
<ul>
<% if(locals.results) { %>
<pre>
<%= JSON.stringify(results,null,2) %>
</pre>
<% results.forEach( function( result ) }) %>
<% } %>
</ul>
</body>
</html>
Do I need to get output from this file?
The data variable is not defined at this point.
You can move your fs.writeFile function in the searchModule.search call like this:
searchModule.search(req.body, function(data) {
fs.writeFile(path,data,function(err){
if(err) console.error(err);
})
res.render('index', { title: 'Express', results: data });
});
or declare your variable before and set it in the searchModule.search call, to be disponible after in the scope to write your file:
var fileData;
searchModule.search(req.body, function(data) {
fileData = data;
res.render('index', { title: 'Express', results: data });
});
fs.writeFile(path,fileData,function(err){
if(err) console.error(err);
})
I'm looking at this block:
fs.writeFile(path,data,function(err){
if(err) console.error(err);
})
You've declared path at the top of your code, but data appears to be undefined in this context.

How to push out requested data from mongodb in node.js

I'm working with Node.js, express, mongodb, and got stuck on this data passing between frontend and backend.
Note: code below is middleware code for front- and backend communication
Here I successfully get the input value from the frontend by using req.body.nr
exports.find_user_post = function(req, res) {
member = new memberModel();
member.desc = req.body.nr;
console.log(req.body.nr);
member.save(function (err) {
res.render('user.jade', );
});
};
Here is the problem, I need to use the input value I got to find the correct data from my database(mongodb in the backend) and push out to the frontend.
My data structure {desc : ''}, the desc is correspond to the input value so it should look something like this {desc: req.body.nr} which is probably incorrect code here?
exports.user = function(req, res){
memberModel.find({desc: req.body.nr}, function(err, docs){
res.render('user.jade', { members: docs });
});
};
Would love to have some help.
Thanks, in advance!
Have a look at this great tutorial from howtonode.org.
Because as you can see he uses a prototype and a function callback:
in articleprovider-mongodb.js
ArticleProvider.prototype.findAll = function(callback) {
this.getCollection(function(error, article_collection) {
if( error ) callback(error)
else {
article_collection.find().toArray(function(error, results) {
if( error ) callback(error)
else callback(null, results)
});
}
});
};
exports.ArticleProvider = ArticleProvider;
in app.js
app.get('/', function(req, res){
articleProvider.findAll( function(error,docs){
res.render('index.jade', {
locals: {
title: 'Blog',
articles:docs
}
});
})
});
Also make sure you have some error checking from the user input as well as from the anybody sending data to the node.js server.
PS: note that the node, express and mongo driver used in the tutorial are a bit older.

Categories