How to show body of a bad request response in angular 4? - asp.net

To provide login error message I added a message in the constructor of Bad Request Response which shows in the postman while testing an web api.
Like this: return BadRequest("Error Message");
Now I want to get that message and display in a component in the client side. But I don't know how to retrieve that. I am trying like this:
signIn() {
this.authService.login(this.loginCredentials).subscribe(result=>{
if(result){
let returnUrl=this.route.snapshot.queryParamMap.get('returnUrl');
this.router.navigate([returnUrl||'/']);
}
},
(err) => {
this.loginMessage=true;
console.log(err.body);
this.invalidLogin=true;
});
}

Finally got it. It will be
console.log(err.body);

Related

Ionic 6 Http Post shows unknown error in normalizedNames for capacitor project

I am calling my Wordpress REST JSON API in my Ionic Capacitor Project.
But i am getting the error shown in image below.
Ionic Capacitor HTTP Error
This is my code
const httpHeader = { // constant for http headers
headers : new HttpHeaders({
'Content-Type':'application/json',
'Access-Control-Allow-Origin': '*'
})
};
createComment(comment: Comment): Observable<any> {
return this.http.post('https://readymadecode.com/wp-json/wp/v2/comments/create,{
"post":4000,
"parent":"0",
"author_name":"chetan",
"author_email":"chetan#gmail.com",
"content":"nice good article"
},httpHeader).pipe(map(this.dataExtract),catchError(this.errorHandler));
}
private dataExtract(res: Response){ // This method extract data from the request response
const body = res;
return body || {};
}
private errorHandler(error: HttpErrorResponse){ // Method for error handler
console.error(error.error instanceof ErrorEvent?`Error message:
${error.error.message}`:`Error status: ${error.error.data.status} Body: ${error.error.message}`);
return throwError(`${error.error.message}`);
}
When i call the createComment function it shows error see in image above. I have tried enable CORS with cordova-plugins-whitelist but still it shows error.
But this api is working fine in postman. I am using this in postman.
URL: https://www.readymadecode.com/wp-json/wp/v2/comments/create
Method: POST
Body: {
"post":4000,
"parent":"0",
"author_name":"chetan",
"author_email":"chetan#gmail.com",
"content":"nice good article"
}
Please help how can i solve this error.
after try all the methods available on google, i able to solve this issue by simply removing the httpHeader from the api.
createComment(comment: Comment): Observable<any> {
return this.http.post('https://readymadecode.com/wp-json/wp/v2/comments/create,{
"post":4000,
"parent":"0",
"author_name":"chetan",
"author_email":"chetan#gmail.com",
"content":"nice good article"
},httpHeader).pipe(map(this.dataExtract),catchError(this.errorHandler));
}

Spark-java redirect - browser does not redirect

Ok, so I try to follow Spark documentation and I want to perform simple redirect in my Single Page Application. My code looks like this:
post("/users/login", (req, res) -> {
ObjectMapper mapper = new ObjectMapper();
User creation = mapper.readValue(req.body(), User.class);
User user = userService.getUser(creation.getLogin());
if (user.getPassword().equals(creation.getPassword())) {
req.session().attribute("userid", creation.getLogin());
System.out.println("OK");
res.status(201);
res.redirect("/index.html");
return "";
}
System.out.println("BAD");
return null;
} , json());
Basically, I have three static html files: registration.html, login.html and index.html. I read stuff concerning staticFileLocation so I added at the beginning of main function following line of code:
staticFileLocation("/public");
When I type correct login and password I find in the network view in Chrome that I have GET request with status 200, OK, to http://localhost:4567/index.html. However, the browser does nothing and does not redirect me to that page. Can you tell me what I am doing wrong?
EDIT:
Here's javascript code that handles log in on the client side:
app.controller('LoginUserCtrl', function($scope, $http) {
$scope.loginUser = {};
$scope.submitForm = function() {
$http({
method : 'POST',
url : 'http://localhost:4567/users/login',
data : $scope.loginUser,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
}
}).success(function() {
console.log("User logged successfully");
console.log($scope.loginUser);
}).error(function() {
console.log("Unknown error while logging user");
});
};
});
What's wrong is that you're redirecting to an HTML page in a post endpoint that's supposed to return Json data. You have to return a single json if authentication succeeded or failed, like {"auth": "OK"} or {"auth": "NOK"}, and decide where to redirect to from Javascript based in it's information.
It's because res.redirect will send a redirect http header(HTTP status values 301, 302, 303 and 307) to the browser,
but the browser only can redirect in get, NOT work in post or put or delete (Tested in chrome. Notice that a redirect request was sent by browser, but the page just not change...).
See:
http://www.alanflavell.org.uk/www/post-redirect.html

Detecting SignalR authorize failures from web client

I'm experimenting with SignalR hosted in an asp.net MVC5 application and am having an issue detecting authorization failures from a web client.
I have a simple hub as follows:
public class ChitChat : Hub
{
[Authorize]
public string Hi(string incoming)
{
Clients.All.echo(incoming);
return "Echoed " + incoming;
}
}
And on the web page:
$(function() {
var hub = $.connection.chitChat;
hub.client.echo = function(msg) {
console.log(msg);
}
$.connection.hub.start().done(function() {
console.log("Done starting hub");
hub.server.hi("Client message")
.done(function() {
console.log(arguments);
})
.fail(function() {
console.log(arguments);
});
})
.fail(function() {
console.log("Fail hub" + arguments);
});
});
When I enable detailed errors in the hub configuration, I get this in the promise rejection for hi
Error: Caller is not authorized to invoke the Hi method on ChitChat.
Without detailed errors, I just get
Error: There was an error invoking Hub method 'chitchat.Hi'.
I'd like to keep detailed errors off, but still get some dependable way of identifying auth failures (I'd assumed I would get a 401/403 code somewhere). Is there a way to achieve this?
SignalR uses jQuery under the hood, so detecting the 401 status code could be achieved by following:
$.ajaxSetup({
statusCode: {
401: function() {
// your code is here
}
}
});
Given a rejection r, check r.source.status. This should give you a 401/403 when it is an authorization problem.

How to show flash notifications after page redirect

Given the following code:
Posts.update(currentPostId, {$set: postProperties}, function(error) {
if (error) {
// display the error to the user
alert(error.reason);
} else {
Router.go('postPage', {_id: currentPostId});
}
});
How does one take the following code and add showing a flash message telling the user that the item has been updated on top of being directed to the new message?
Have you looked at the various flash message packages?
naxio:flash in particular supports iron:router.

I need two instances of AngularJS $http service or what?

I want add a response interceptor to my $http service for error handling purposes. The interceptor logic include send errors messages to server using $http in case necessary, BUT I don't want send errors messages to the server about errors messages, I mean, I want disable my interceptor while sending error message to the server.
My idea was create a service named 'remote_log' and put inside it all the code needed to send error to server. That service of course will use the $http service and have it in its dependency list.
Then add as dependency of the interceptor to the 'remote_log' service, and use the 'remote_log' inside the interceptor when need send errors to the server. The problems is that:
Interceptors must be defined using the $httpProvider when the $http service still is not instantiated/accessible, so, inside the interceptor code can't be a dependency to that the $http service because a "Circular dependency" error happen.
I think my only option is create a separate instance of the $http service inside my 'remote_log', an instance that don't uses the $httpProvider configuration I set while creating the interceptor. My question is: How can I do that? Any other ideas?
1. Circular dependency problem.
So, why does the error appear? Here is a quick overview of the process:
$http service is requested.
$httpProvider is asked to construct it.
During construction you register interceptor, that requests $http service not existing yet.
You get "Circular dependency" error.
First solution.
Create your dependency using angular.injector(). Notice, that you will create another $http service, independent from your app.
$httpProvider.interceptors.push(function($q) {
$injector = angular.injector();
return {
response: function(response) {
$injector.invoke(function($http) {
// This is the exterior $http service!
// This interceptor will not affect it.
});
}
};
});
Second solution (better).
Inject $injector in your interceptor and use it to retrieve dependencies after $http initialization, right at the time you need them. These dependencies are registered services of your app and will not be created anew!
$httpProvider.interceptors.push(function($q, $injector) {
return {
response: function(response) {
$injector.invoke(function($http, someService) {
// $http is already constructed at the time and you may
// use it, just as any other service registered in your
// app module and modules on which app depends on.
});
}
};
});
2. Interception prevention problem.
If you use the second solution, there are actually two problems:
If you utilize $http service inside your
interceptor, you may end up with infinite interceptions: you send
request, interceptor catches it, sends another, catches another,
send again, and so on.
Sometimes you want just prevent request from being intercepted.
The 'config' parameter of $http service is just an object. You may create a convention, providing custom parameters and recognizing them in your interceptors.
For example, let's add "nointercept" property to config and try duplicate every user request. This is a silly application, but useful example to understand the behavior:
$httpProvider.interceptors.push(function($q, $injector) {
return {
response: function(response) {
if (response.config.nointercept) {
return $q.when(response); // let it pass
} else {
var defer = $q.defer();
$injector.invoke(function($http) {
// This modification prevents interception:
response.config.nointercept = true;
// Reuse modified config and send the same request again:
$http(response.config)
.then(function(resp) { defer.resolve(resp); },
function(resp) { defer.reject(resp); });
});
return defer.promise;
}
}
};
});
Having the testing for property in interceptor, you may prevent the interception in controllers and services:
app.controller('myController', function($http) {
// The second parameter is actually 'config', see API docs.
// This query will not be duplicated by the interceptor.
$http.get('/foo/bar', {nointercept: true})
.success(function(data) {
// ...
});
});
I used what is described in the answer but I used the syntax with a factory because with the anonymous function it didn't work, I don't really know why:
(function(angular){
angular.module('app', [])
.config([
'$httpProvider',
function($httpProvider) {
$httpProvider.interceptors.push('Interceptor');
}
])
.factory('Interceptor', [
'$injector',
InterceptorFactory
]);
function InterceptorFactory($injector){
return {
request: function(config) {
var ServiceWithHttp = $injector.get('ServiceWithHttp');
// Use ServiceWithHttp
return config;
}
};
}
}(window.angular));

Resources