function returns a promise reject when resolved - javascript

I have a angularjs controller and factory.
So my purpose is to manage all the message errors depending of the promise result. That means to receive in the controller a reject after checking some bad values in the resolve factory function.
I'm trying this way but it doesn't work:
factory.js
var mediaRecent;
function getMediaByUserName(user) {
return $http.get('https://www.instagram.com/' + user + '/media')
.then(function (response) {
if (response.data.items.length === 0) {
// I want here to cause a reject in the controller function
return new Error('This user is not public');
}
mediaRecent = response.data.items;
})
.catch(function (error) {
return new Error('There was a problem looking to that user');
});
}
controller.js
instagramFactory.getMediaByUserName(vm.name)
.then(function () {
$state.go('instagramMediaRecent');
})
.catch(function (error) {
vm.error = error.message;
});

var mediaRecent;
function getMediaByUserName(user) {
return $http.get('https://www.instagram.com/' + user + '/media')
.then(function (response) {
if (response.data.items.length === 0) {
// go to catch() from here
return $q.reject(new Error('This user is not public'));
}
mediaRecent = response.data.items;
})
.catch(function (error) {
return new Error('There was a problem looking to that user');
});
}

Actually you called promise twice. So you can call it only in Controller or Factory.
Simple way
Factory:
function getMediaByUserName(user) {
return $http.get('https://www.instagram.com/' + user + '/media');
}
Controller:
instagramFactory.getMediaByUserName(vm.name)
.then(function () {
if (response.data.items.length === 0) {
// I want here to cause a reject in the controller function
return new Error('This user is not public');
}
var mediaRecent = response.data.items;
$state.go('instagramMediaRecent');
})
.catch(function (error) {
vm.error = new Error('There was a problem looking to that user');
});

Related

How can return false value promise method in node if array is empty and vise versa

i was trying out promise code but it always returns me resolve even if the user does not exist in the database
can anyone help me fix my code and the return statement
in the return function the the second console log is only working.
here is my code
Api Call
const email = 't#t.com';
const request = require('request');
function IsUserExists(email, kc_accessToken) {
let url = `${path}/users?email=${email}`;
return new Promise(function (resolve, reject) {
request(
{
url: url,
headers: {
'content-type': 'application/json',
authorization: `Bearer ${kc_accessToken}`,
},
},
function (error, response, body) {
if (error) {
console.log('some error occured');
}
if (response.body.length > 0) {
console.log('User Exist');
return resolve();
}
console.log('Does not Exist');
return reject();
}
);
});
}
Function Call
http
.createServer(function Test() {
getAccessToken()
.then(function (response) {
kc_accessToken = response.data.access_token;
IsUserExists(email, kc_accessToken).then((resp) => {
if (resp) {
console.log('Do Not Create');
} else if (!resp) {
console.log('Creat a new User');
}
});
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
})
.listen(8081);
When Provided user email which exist ( t#t.com )
When Provided user email which does not exist( 09#t.com )
I need to create a new answer for example to you question in comments.
Now, you go into the reject function so you need to handle this rejection in the outside.
if (response.body.length > 0) {
console.log('User Exist');
return resolve();
}
console.log('Does not Exist');
return reject(); // -> Now here you are
You need add .catch function after IsUserExists.then().
It will be IsUserExists.then().catch()
http.createServer(function Test() {
getAccessToken()
.then(function (response) {
kc_accessToken = response.data.access_token;
// here you only accept the data from resolve in Promise
// so you need to add .catch function to handle the rejection.
IsUserExists(email, kc_accessToken).then((resp) => {
if (resp) {
console.log('Do Not Create');
} else if (!resp) {
console.log('Creat a new User');
}
}).catch((error) => {
console.log(error)
});
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
})
.listen(8081);
By the way, you could add parameter in rejection function like reject(new Error("user not found)).
Then in the outside, you can get this rejection message.

Using promises with AngularJS

I have this service
service.getCurrentUser = function () {
var def = $q.defer(); 
if (service.user == null)
{
$http.get("./api/GetCurrentUser/")
.success(function(data) { 
service.user=data; 
def.resolve(data); 
}) 
.error(function() { 
def.reject("Failed to get user"); 
}); 
}
else
def.resolve(service.user);
return def.promise;
} 
in my controller I want to call this and wait for return then if the user is in a certain group run other code
How do I write it so it uses the promise returned by the service
The promise implementation can be like:
service.getCurrentUser = function () {
return new Promise((resolve,reject)=>{
if (service.user == null) {
$http.get("./api/GetCurrentUser/")
.success(function (data) {
service.user = data;
resolve(data);
})
.error(function () {
reject("Failed to get user");
});
}else{
resolve(service.user);
}
});
}
You can call it as:
service.getCurrentUser()
.then(user => {
console.log('user', user);
})
.catch(error => {
console.log('error', error);
});

Don't work function with promise

I try this code:
function addNewCars(req, res) {
let CarsList = req.body;
carListParsing(carList)
.then(function () {
console.log('OK');
res.status(200).send('OK');
}).catch(function (err) {
res.status(200).send(err);
});
}
function carListParsing (data) {
return new Promise(function (resolve, reject) {
let newCar = {};
newCar.name = data.car_name;
validateCar(newCar).then(function (data) {
console.log('validate result1: ', data); //this line doesn't show
//if I get validation result, I can use next function createCat()
resolve(data);
}).catch(function (err) {
reject(err);
});
});
}
function validateCar(data) {
db.cars.findAll({where: {name: data.name}}).then(function (org) {
if (org.length < 1) {
console.log('validate1: OK'); //work
return data;
} else {
console.log('validate2: already exist'); //work
return new Error('The ' + data.name + ' car is already exist.');
}
}).catch(function (err) {
return err;
});
}
I neet to validate data => Car name, if car not exist then create new car and perform next logic, example park car. If car found, then perform function park car.
Avoid the Promise constructor antipattern in carListParsing, and return your result promise from validateCar!
function addNewCars(req, res) {
// CarsList is a typo
carListParsing(req.body)
.then(function () {
console.log('OK');
res.status(200).send('OK');
}, function (err) { // more appropriate than catch
res.status(200).send(err);
});
}
function carListParsing (data) {
let newCar = {
name: data.car_name
};
// don't call `new Promise`
return validateCar(newCar).then(function (data) {
console.log('validate result1: ', data); //this line doesn't show
// if I get validation result, I can use next function createCat()
return data; // don't resolve
});
}
function validateCar(data) {
return db.cars.findAll({where: {name: data.name}}).then(function (org) {
// ^^^^^^
if (org.length < 1) {
console.log('validate1: OK'); //work
return data;
} else {
console.log('validate2: already exist'); //work
throw new Error('The ' + data.name + ' car is already exist.');
// ^^^^^ probably what you actually wanted
}
}) // don't ignore errors
}

Unhandled promise rejection Error: Can't set headers after they are sent

I would like to make a if else return (for conrtole) but: "UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Can't set headers after they are sent.
"
exports.delete = function (req, res) {
Parking.findById(req.params.id).exec()
.then(function (parking) {
if (userController.ensureAuthorized(req, 'Director', parking.id)) {
return parking;
}
return res.status(403).send({msg: 'unauthorized'});
})
.then(function (parking) {
User.update().exec();
return parking;
})
.then(function (parking) {
return Parking.remove({_id: parking._id}).exec();
})
.then(function () {
res.status(200).json({msg: 'Ok ! Parkink remove'});
})
.catch(function (err) {
return res.status(400).send(err);
});
};
Ty
The issue is that after return res.status(403), the promise chain doesn't stop automagically. Eventually, it will hit res.status(200) and cause the error.
You can rewrite your promise chain a bit to prevent this. I'm not sure what the purpose of that User.update().exec() is, but I assume that you wanted to call it and also wait for its promise to get resolved before continuing:
exports.delete = function (req, res) {
Parking.findById(req.params.id).exec()
.then(function (parking) {
if (userController.ensureAuthorized(req, 'Director', parking.id)) {
return User.update(...).exec().then(function() {
return Parking.remove({_id: parking._id}).exec();
}).then(function() {
return res.status(200).json({msg: 'Ok ! Parkink remove'});
});
} else {
return res.status(403).send({msg: 'unauthorized'});
}
}).catch(function (err) {
return res.status(400).send(err);
});
};
Well there is no standard way of breaking the promise chain.
So I am going to throw an error to break the chain, and then handle that custom thrown error:
exports.delete = function (req, res) {
Parking.findById(req.params.id).exec()
.then(function (parking) {
if (userController.ensureAuthorized(req, 'Director', parking.id)) {
return parking;
}
else {
res.status(403).send({msg: 'unauthorized'});
throw new Error('BREAK_CHAIN'); // <-- intentionally throw error
}
})
.then(function (parking) {
User.update().exec();
return parking;
})
.then(function (parking) {
return Parking.remove({_id: parking._id}).exec();
})
.then(function () {
res.status(200).json({msg: 'Ok ! Parkink remove'});
})
.catch(function (err) {
if(err.message != 'BREAK_CHAIN') // <-- handle if error was intentionally thrown
return res.status(400).send(err);
});
};
just as an addition to the other answers given, I would recommend:
1) breaking things up into small parts
2) using throw as intended, to raise the error of non-authorization
function update (parking) {
User.update().exec()
.then(function () {
Parking.remove({_id: parking._id}).exec();
});
}
exports.delete = function (req, res) {
// auth needs req so we put it in scope
var auth = function (parking) {
if (!userController.ensureAuthorized(req, 'Director', parking.id)) {
throw(new Error(403));
}
return parking;
}
Parking.findById(req.params.id).exec()
.then(auth)
.then(update)
.then(function () {
res.status(200).json({msg: 'Ok ! Parkink remove'});
})
.catch(function (err) {
if (err.message === 403) {
return res.status(403).send({msg: 'unauthorized'});
}
return res.status(400).send(err);
});
};

Bluebird promises - nesting vs rejecting pattern

I'm working on an app for which we're using promises. I'm attempting to figure out what the better pattern is.
Breaking up concerns between thenables and rejecting the promise if an error. Rejection is then handled in a catch block. Or is it better to throw a new type of error and handle in the catch block?
Account.findOneAsync({email: request.payload.email})
.then(function (user) {
if (user) {
return user.compareHash(request.payload.password);
} else {
// Account not found
return Bpromise.reject('AccountNotFound');
}
})
.then(function (validPassword) {
if (validPassword) {
return request.auth.jwt.user.sign();
} else {
// Invalid password
return Bpromise.reject('InvalidPassword');
}
})
.then(function (jwt) {
var response = reply.success();
return response.header('authorization', jwt);
})
.catch(function (e) {
if (e === 'AccountNotFound' || e === 'Invalid Password') {
return reply(Boom.unauthorized('Invalid username/password'));
} else {
// Perhaps log something like unhandled error
return reply(Boom.unauthorized('Invalid username/password'));
}
});
Or nesting promising as such. I feel here that this is just going down the same rabbit hole of "callback hell" though.
Account.findOneAsync({email: request.payload.email})
.then(function (user) {
if (user) {
user.compareHash(request.payload.password)
.then(function (valid) {
if (valid) {
request.server.plugins.jwt.sign()
.then(function (jwt) {
var response = reply.success();
return response.header('authorization', jwt);
});
} else {
// Invalid password
return reply(Boom.unauthorized('Invalid username/password'));
}
});
} else {
// Account not found
return reply(Boom.unauthorized('Invalid username/password'));
}
})
.catch(function (e) {
console.log(e);
});
I think you can get the best of both worlds by throwing and then catching your boom objects.
One thing you're missing in both approaches is that when you're already inside a then handler, the idiomatic thing to do is throw an error rather than creating and returning a rejected promise. You also don't need an else block after a return statement:
Account.findOneAsync({email: request.payload.email})
.then(function (user) {
if (user) {
return user.compareHash(request.payload.password);
}
// Account not found
throw Boom.unauthorized('Invalid username/password');
})
.then(function (validPassword) {
if (validPassword) {
return request.auth.jwt.user.sign();
}
// Invalid password
throw Boom.unauthorized('Invalid username/password');
})
.then(function (jwt) {
var response = reply.success();
return response.header('authorization', jwt);
})
.catch(function (e) {
if (e.isBoom) {
return reply(e);
}
// Perhaps log something like unhandled error
return reply(Boom.unauthorized('Invalid username/password'));
});

Categories

Resources