Catching errors in AngularJS when using $resource - javascript

Searching product is working fine when product is found, but if user search with letters, or bad criteria, nothing happens. I can see the error message in JavaScript-console and in Header there is Status Code 204, no Content. I think that Angular is just working badly, when empty object is coming back. How can I tell an user that there is no products with his/her criteria, cause I can't catch the error message at all at the moment. What is the correct and best solution to handle this? Catching errors or solving that result was empty and showing an error message in HTML-page?
Service:
return $resource(
'http://localhost:8080/RMAServer/webresources/com.rako.entity.jdeserials/:id',
{},
{
get: { method: 'GET',isArray:false, params: {id: '#serial'} },
update: { method: 'PUT', params: {id: '#serial'} }
});
Controller
//Searching product with serial number/LOTN
$scope.searchProduct = function () {
$scope.serials = lotnSvc.get({id: $scope.serial}).$promise.then(
function (data) {
var litm = data.litm;
productSvc.get({id: litm}, function (product) {
$scope.product = product;
getBrands();
},function(error){
alert('ERROR when searching product');
console.log("error---->" + error);
});
},function(error){
alert('ERROR when searching product');
console.log("error---->" + error);
});
};
Error message in javaScript console
Error: [$resource:badcfg] Error in resource configuration for action `get`. Expected response to contain an object but got an array
http://errors.angularjs.org/1.3.15/$resource/badcfg?p0=get&p1=object&p2=array
at REGEX_STRING_REGEXP
Status code in Header

Just try to send the success and the error handlers as second and third parameters to "get" function instead of using promises. There was the same problem: How to handle $resource service errors in AngularJS

Related

Parse-server social login

I am developing application based on Parse-server and I want to offer social login. I found this guide in the documentation http://docs.parseplatform.org/js/guide/#linking-users.
I started to implement the social login by google. I did following steps:
1) I added following lines to the ParseServer settings
var api = new ParseServer({
...
auth:{
google: {}
},
...
});
2) I did the authentication by hello.js on the client side (call user._linkWith function on login)
hello.init({
google: 'My Google id'
});
hello.on('auth.login', function(auth) {
// Call user information, for the given network
hello(auth.network).api('me').then(function(r) {
const user = new Parse.User();
user._linkWith(auth.network, auth.authResponse).then(function(user){
console.log('You are logged in successfully.');
});
});
});
When I debugged it, I found that it fails in _linkWith() function, when provider object is preparing. Object AuthProviders, which should store all providers, is empty. Because of it the statement provider = authProviders['google']; leads to undefined. Invoking provider.authenticate(...); leads to error "Cannot read property 'authenticate' of undefined"
What am I missing or what am I doing wrong?
Thanks for all your answers.
Honza
Did you register the authenticationProvider? You can find examples in our unit tests on how to do so:
https://github.com/parse-community/parse-server/blob/5813fd0bf8350a97d529e5e608e7620b2b65fd0c/spec/AuthenticationAdapters.spec.js#L139
I also got this error and looked at the _linkWith(provider, options) source code. It checks if options has an authData field (which in turn should contain id and credentials). If so, it uses options.authData. Otherwise it falls back on looking up a previously registered authentication provider mentioned in the previous answer.
This is a fragment of the code I'm using:
const authData = {
"id": profile.getId(),
"id_token": id_token
}
const options = {
"authData": authData
}
const user = new Parse.User();
user._linkWith('google', options).then(function(user) {
console.log('Successful user._linkWith(). returned user=' + JSON.stringify(user))
}, function(error) {
console.log('Error linking/creating user: ' + error)
alert('Error linking/creating user: ' + error)
// TODO handle error
})

Vuejs won't let me console.log within request

In the methods section of my Vue.js script im trying to do a console.log but nothing is happening, in fact i can do no javascript at all within this section but the request to '/register' remains working.
postRegister: function(){
//code here works fine
console.log('working')
this.$http.post('/register', this.user, function(response){
//Any code here does not work even though the request itself has worked
console.log('not working');
});
}
My Controller
public function Register(Request $request)
{
$validator = Validator::make($request->all(), [
'username' => 'required|unique:users|max:12',
'email' => 'required|unique:users|email',
'password' => 'required|confirmed'
]);
if ($validator->fails()) {
return $validator->errors()->all();
}
}
As i originally said, everything works the validator returns the correct responses and everything and the post attempt is made successfully, there is no console data being logged however within the http post request!
Since you are using the validator you're not getting back a 200 status code and that's why the success function will not get triggered. You should catch the error and then console.log it:
this.$http.post('/register', this.user)
.then(function(response){
console.log(response);
})
.catch(function(error){
console.log(error);
});

ngResource + 401 error handling: Expected response either an array or an object

I am using the following code with ngResource to retrieve a list of objects:
// Create the 'articles' service
angular.module('articles').factory('Articles', ['$resource', function($resource) {
// Use the '$resource' service to return an article '$resource' object
return $resource('../api/admins/:adminId/articles/:articleId', {
adminId: '#adminId'
}, {
update: {
method: 'PUT'
}
});
}]);
Articles are retrieved like so:
$scope.list = function() {
// Use the articles'query' method to send an appropriate GET request
Articles.query(
function(articles){
$scope.data.articles= articles;
},
function(error){
console.log(error);
}
);
};
When a user is logged in, all works fine: The client expects an array and that's what it gets.
But after a while when the login timed out, the server will return a 401 error with an object instead of an array. In fact, this is EXACTLY what is supposed to happen, but Angular throws the following error:
Error: [$resource:badcfg] Error in resource configuration.
Expected response to contain an array but got an object
The same problem occurs when a user retrieves a page that is forbidden (403).
Is there a way to resolve 401 and 403 request errors without getting an actual javascript error in Angular?
the query action of $resource by default expects an array to be returned from the server (see the docs).
You could use the transformResponse option for the query action to compensate for this like so:
return $resource('../api/admins/:adminId/articles/:articleId', {
adminId: '#adminId'
}, {
update: {
method: 'PUT'
},
query: {
transformResponse: function(data, headers) {
if(!angular.isArray(data)) {
return new Array(data);
}
return data;
}
}
});
Of course it would be much better to handle errors using the error callback or with an interceptor

Ember data: Rollback createRecord on error

I'm trying to find the best way to avoid adding a record when there's an error using Ember Data:
This is my code:
createUser: function() {
// Create the new User model
var user = this.store.createRecord('user', {
firstName: this.get('firstName'),
lastName: this.get('lastName'),
email: this.get('email')
});
user.save().then(function() {
console.log("User saved.");
}, function(response) {
console.log("Error.");
});
},
I'm validating the schema on backend and returning a 422 Error in case it fails.
If I don't handle the error, the record is added to the site and I also get a console error.
So I did this:
user.save().then(function() {
console.log("User saved.");
}, function(response) {
user.destroyRecord();
});
Which kind of works deleting the record after reading the server response but:
1) I see the record appearing and dissapearing (like a visual glitch to say it somehow).
2) The console error still appears.
Is there a way to better handle this? I mean, is there a way to avoid adding the record when the server returns an error? Is there a way to avoid showing the console error?
Thanks in advance
You'll need to catch the error in the controller and then use deleteRecord() to remove it from the store:
actions: {
createContent() {
let record = this.store.createRecord('post', {
title: ''
});
record.save()
.then(rec => {
// do stuff on success
})
.catch(err => {
record.deleteRecord();
// do other stuff on error
});
}
}

ExpressJS why is my GET method called after my DELETE method?

In my express app, when the DELETE method below is called, the GET method is immediately called after and it's giving me an error in my angular code that says it is expected an object but got an array.
Why is my GET method being called when i'm explicitly doing res.send(204); in my DELETE method and how can I fix this?
Server console:
DELETE /notes/5357ff1d91340db03d000001 204 4ms
GET /notes 200 2ms - 2b
Express Note route
exports.get = function (db) {
return function (req, res) {
var collection = db.get('notes');
collection.find({}, {}, function (e, docs) {
res.send(docs);
});
};
};
exports.delete = function(db) {
return function(req, res) {
var note_id = req.params.id;
var collection = db.get('notes');
collection.remove(
{ _id: note_id },
function(err, doc) {
// If it failed, return error
if (err) {
res.send("There was a problem deleting that note from the database.");
} else {
console.log('were in delete success');
res.send(204);
}
}
);
}
}
app.js
var note = require('./routes/note.js');
app.get('/notes', note.get(db));
app.post('/notes', note.create(db));
app.put('/notes/:id', note.update(db));
app.delete('/notes/:id', note.delete(db));
angularjs controller
$scope.delete = function(note_id) {
var note = noteService.get();
note.$delete({id: note_id});
}
angularjs noteService
angular.module('express_example').factory('noteService',function($resource, SETTINGS) {
return $resource(SETTINGS.base + '/notes/:id', { id: '#id' },
{
//query: { method: 'GET', isArray: true },
//create: { method: 'POST', isArray: true },
update: { method: 'PUT' }
//delete: { method: 'DELETE', isArray: true }
});
});
** UPDATE **
To help paint the picture, here's the angular error i'm getting:
Error: [$resource:badcfg] Error in resource configuration. Expected response to contain an object but got an array http://errors.angularjs.org/1.2.16/$resource/badcfg?p0=object&p1=array
I'm assuming that i'm getting this error because my delete method is calling my get method (somehow) and the get method returns the entire collection.
Server side
You're removing an element from a collection in your delete function. This is done asynchronously and calling your callback when it's finished.
During this time, other requests are executed, this is why your GET request is executed before your DELETE request is finished.
The same happens in your get function, you're trying to find an element from a collection and this function is too asynchronous.
But this is server side only and it is fine, it should work this way, your problem is located client side.
Client side
If you want to delete your note after you got it, you will have to use a callback function in your angular controller which will be called only when you got your note (if you need help on that, show us your noteService angular code).
This is some basic javascript understanding problem, actions are often made asynchronously and you need callbacks to have an execution chain.
Maybe try doing something like this:
$scope.delete = function(note_id) {
var note = noteService.get({ id: note_id }, function()
{
note.$delete();
});
}
Your code doesn't make sense though, why is there a get in the $scope.delete? Why not do as simply as following:
$scope.delete = function(note_id) {
noteService.delete({ id: note_id });
}
Error
I think you get this error because of what your server sends in your exports.delete function. You're sending a string or no content at all when angular expects an object (a REST API never sends strings). You should send something like that:
res.send({
results: [],
errors: [
"Your error"
]
});

Categories

Resources