Error when getting data from MongoDB - node.js

Yesterday I faced with unusual behavior for MongoDB.
So.. I store countries and languages with their codes in collections and when client side application need this data - it sends 'get' request to get data. It happens simultaneously
function init() {
helperService
.getCountries()
.then(success)
.catch(commonService.handleError);
function success(res) {
self.countries = res.data;
}
}
function init() {
helperService
.getLanguages()
.then(success)
.catch(commonService.handleError);
function success(res) {
self.languages = res.data;
}
}
Here I send request to get data in angular component $onInit
Backend code looks pretty simple:
var country = require('countryModel');
var language = require('languageModel');
function getCountries(req, res, next) {
return country
.find({})
.then(success)
.catch(next);
function success(data) {
res.json(data);
}
}
function getLanguages(req, res, next) {
return language
.find({})
.then(success)
.catch(next);
function success(data) {
res.json(data);
}
}
Locally all works as expected. But after deploying application on linux server I often see error 404 'Cannot GET /api/language' and 'Cannot GET /api/country'. Sometimes I got data but more often I got one error or this two errors above.
Could anybody give me idea what is wrong?

It seems to me that you have problems with registering routes. Check it please

Related

same base url with different functionalities nodejs

app.get('/api/v3/app/events', async function (req, res){
try {
let unique_id=req.query.id
console.log(unique_id)
database.collection('event').findOne(ObjectId(unique_id),function(err,data){
if(err){
res.json({error:"no data found with specified id"})
}
console.log(data)
res.json(data)}
)
} catch (error) {
console.log("internal error")
res.json({error:error})
}
})
app.get('/api/v3/app/events', function(req,res) {
try {
let limit=parseInt(req.query.limit)
let page =parseInt(req.query.page)
console.log(database.collection('event').find().sort({$natural: -1}).limit(limit).skip(page-1).toArray((err, result) => {
console.log(result);
})
)
} catch (error) {
console.log(error)
return res.json({error:"internal error "})
}
})
I have to perform these functionalities with same base url i.e '/api/v3/app/events'.
Please help . I am successful as I change the names of endpoints, but keeping them same , I gets null and undefined on the console
I'm not sure why do you need both to use same URL, but you have two choices either use a single endpoint with both of the logics. The other option would be to use the next middleware based on the id query param like this:
app.get('/api/v3/app/events', async function (req, res, next){
if (!req.query.id) {
next();
return;
}
// Rest of your endpoint logic
}
Each endpoint in Express is considered as middleware. This means that response won't be sent back, but calling the next() middleware instead and allow other middlewares to be executed. You can use same if or modify it based on your login.

Not able to call a backend function 404 not found

I am running a Express application with Node in the backend. I have 2 functions in a component in NodeJS which I am trying to access from my service. The link for both are the same in the service. It is able to connect one of the functions from the service.
However, it is showing 404 not found for accessing the second function in the same component. It is strange that the 2 functions from the same service is are giving 2 different responses (1 success and 1 failure).
Has anyone faced any such issue and if so how can it be rectified?
Some code for reference :
component1.component.ts
getallprojectcat()
{
this.authenticationService.getprojectcat()
.pipe(first())
.subscribe(
data => {
this.data = data;
},
error => {
this.loading = false;
});
}
}
component2.component.ts
showprojects(moid)
{
this.authenticationService.getprojectslist(moid)
.pipe(first())
.subscribe(
data => {
this.silver = data;
},
error => {
console.log('some error');
this.alertService.error(error);
this.loading = false;
});
}
the .service file
getprojectcat()
{
return this.http.get<any>(this.studenturl+'/getprojectcata/')
.pipe(map(allprojectcat => {
console.log(JSON.stringify(allprojectcat));
return allprojectcat;
}));
}
getprojectslist(moid)
{
return this.http.get(this.studenturl+'/getprojects/'+moid)
.pipe(map(projectslist => {
console.log("Projects List:"+JSON.stringify(projectslist));
return projectslist;
})).catch(this.handleError);
}
Backend .js file
exports.getprojectcata = function(req, res){
console.log("First Function");
};
exports.getprojects = function(req, res){
console.log("Second Function");
};
The function getprojectcata is working in the first component. However, it shows an 404 not found on the getprojects function in the second component. I have checked the following things -
Routing does not seem to be the problem as it is moving to the next component without any issues.
We have also tried calling the getprojectscata through the same service in component and it worked.
For sencond function use .post in service and backend route also.
As GET requests is only used to request data. And you are passing moid in http.get which gives 404.
In post you can send moid data in params and in backend fetch data as req.params.
I hope it wil help you .
Share your code for better understanding.

Bad Request error in uber api

I've been trying to get the uber price estimates endpoint working, but I'm stuck on an error that leads me to a blank page saying, "Bad Request." The console also says "callback not a function" but I can't seem to find out what is wrong.
My route:
// Get an upfront fare before requesting a ride
app.get('/v1.2/estimates/price', function(request, response) {
// extract the query from the request URL
var query = request.query;
// if no query params sent, respond with Bad Request
if (!query || !query.lat || !query.lng) {
response.sendStatus(400);
} else {
uber.estimates.getPriceForRouteAsync( {
"product_id": "33de8094-3dc4-4ca9-8f67-243275f57623",
"start_latitude": "38.9597897",
"start_longitude": "-94.60699369999999",
"end_latitude": "39.010969",
"end_longitude": "-94.61509899999999"
})
.then(function(res) {
log(res);
})
.error(function(err) {
console.error(err);
});
}
});
Any help is appreciated.
Please check out the README for node-uber. The method does not take a JSON object but the arguments in the method call:
uber.estimates.getPriceForRouteAsync(38.9597897, -94.606994, 39.010969, -94.615098)
.then(function(res) { console.log(res); })
.error(function(err) { console.error(err); });
Also, the product ID is not needed as the /estimates/price endpoint returns an array of estimates for each product.

NodeJs http status exception handling

I have created nodejs + express application. Now in my application when exception caught errors are send as follows
app.get('/data', (req, res) => {
if(!req.params.token){
return res.status(403).send('Access token not provided');
}
//do something here
});
Instead of sending res.status(403).send('Access token not provided'); can I send something like this
exception.js
class Forbidden {
constructor(message,stack = null){
this.code = 403;
this.message = message
this.stack = stack;
}
}
app.js
var httpForbidden = require('exception.js');
app.get('/data', (req, res) => {
if(!req.params.token){
return new httpForbidden ('Access token not provided');
}
//do something here
});
And also how can I caught all exceptions in once place ?
You could use something like this:
class httpError {}
class httpForbidden extends httpError {
constructor(message, stack = null) {
super();
this.code = 403;
this.message = message
this.stack = stack;
}
}
app.get('/', (req, res) => {
if (!req.params.token) {
throw new httpForbidden('Access token not provided');
}
...
});
app.use((err, req, res, next) => {
if (err instanceof httpError) {
return res.status(err.code).send(err.message);
}
res.sendStatus(500);
});
This uses an Express error handling middleware that will check if the error that got thrown is an instance of httpError (which would be the superclass of all the HTTP error classes that you'd want to create) and, if so, would generate a particular response according to the code and the message (or generate a generic 500 error response otherwise).
I like to create a separate function, along with other utility functions ( say in lib.js), which creates a properly formatted JSON response object and selects the appropriate logger to log response depending upon the HTTP status code.
lib.js
var logger = require("./loggger");
module.exports.sendResponse = function (res,code,message,data) {
if(code<100 || code>599) {
throw new Error("response cannot be sent. Invalid http-code was provided.");
}
var responseLogger = code>=500 ? logger.error : logger.debug;
var responseObject = {
"code" : code,
"message" : message
};
if(data) {
responseObject.data = data;
}
responseLogger(responseObject);
res.status(code).json(responseObject);
};
app.js
var lib = require("./lib");
/*
Relevant Express server code
*/
app.get('/data', function (req,res) {
if(!req.params.token){
return lib.sendResponse(res,403,"Access token not provided");
}
// Rest of business logic
});
Note : You can write your own logging functionality, but I strongly suggest to build it upon some standard logging library like winston)
Below method is deprecated as the boom is changes to #hapi/boom,
https://hapi.dev/family/boom/?v=8.0.1
here you find whole documentation of #hapi/boom library
-----deprecated-------
You can use boom library instead, which provides a set of utilities for returning HTTP errors
HTTP 4xx Errors
Boom.badRequest([message], [data])
Boom.unauthorized([message],[scheme], [attributes])
HTTP 5xx Errors
Boom.badImplementation([message], [data]) - (alias: internal)
Boom.notImplemented([message], [data])
for more api documentation visit here
You can use:
res.code(403).json({message: '...', stack: '...'});
and send whatever you want. But you do it with calling methods on the response object.
And also how can I caught all exceptions in once place ?
Very bad idea. You should handle all errors where they happen so that you can still have some context to handle them in a reasonable way. Otherwise you can just throw exceptions and return 500 errors.

Define/Use a promise in Express POST route on node.js

I currently have a POST route defined in an Express Node.js application as so:
var locationService = require("../app/modules/locationservice.js");
app.post('/createstop', isLoggedIn, function(req, res) {
locationService.createStop(res, req.body);
});
(for this question, please assume the routing in & db works.. my record is created on form submission, it's the response I am struggling with)
In the locationservice.js class I then currently have
var models = require('../models');
exports.createStop = function(res, formData) {
models.location.build({ name: formData.name })
.save()
.then(function(locationObj) {
res.json({ dbResult : locationObj });
});
};
So as you can see, my route invokes the exported function CreateStop which uses the Sequelize persistent layer to insert a record asynchronously, after which I can stick the result on the response in the promised then()
So at the moment this only works by passing the response object into the locationservice.js method and then setting res.json in the then() there. This is sub-optimal to me with regards to my service classes, and doesn't feel right either.
What I would like to be able to do is "treat" my createStop method as a promise/with a callback so I can just return the new location object (or an error) and deal with it in the calling method - as future uses of this method might have a response context/parameter to pass in/be populated.
Therefore in the route I would do something more like:
var locationService = require("../app/modules/locationservice.js");
app.post('/createstop', isLoggedIn, function(req, res) {
locationService.createStop(req.body)
.then(dataBack) {
res.json(dataBack);
};
});
Which means, I could call createStop from else where in the future and react to the response in that promise handler. But this is currently beyond me. I have done my due diligence research, but some individual expert input on my specific case would be most appreciated.
Your locationservice.js could look like that
exports.createShop = function(data){
// here I have used create instead of build -> save
return models.location.create(data).then(function(location){
// here you return instance of saved location
return location;
});
}
And then your post() method should be like below
app.post('/createstop', isLoggedIn, function(req, res){
locationService.createShop(req.body).then(function(location){
// here you access the location created and saved in createShop function
res.json(location);
}).catch(function(error){
// handle the error
});
});
Wrap your createStop function with a promise like so:
exports.createStop = function(res, formData) {
return new Promise(function(resolve, reject) {
models.location.build({ name: formData.name })
.save()
.then(function(locationObj) {
resolve({ dbResult : locationObj });
});
//in case of error, call reject();
});
};
This will allow you to use the .then after the createStop within your router.

Resources