I have configured my application to send a confirmation Email to the user after registration. After the registration is completed the user will see a page that is saying you need to confirm you Email:
<div *ngIf="!emailConfirmed">
<p> Please activate your account by clicking the relevant link in your Email </p>
</div>
<div *ngIf="emailConfirmed">
<p>
Your Email is now confirmed, please click the below button to Log-In.
</p>
<a class="btn btn-md btn-success btn-color" [routerLink]="['/login']">
Sign In
</a>
</div>
And emailConfirmed
is just a simple variable that I have defined in the emailConfirmed's typescript relevant file:
export class EmailConfirmed {
public emailConfirmed: boolean;
}
After the user clicks on the link in his/her Email, his/her account will be verified and then the application will be redirected to the ConfirmEmail
page again using the below code:
[HttpGet]
[Route("ConfirmEmail", Name = "ConfirmEmailRoute")]
public async Task<IActionResult> ConfirmEmail(string userId = "", string code = "")
{
//....
IdentityResult result = await UserManager.ConfirmEmailAsync(userId, code);
if (result.Succeeded)
{
return Redirect("http://localhost:5000/emailconfirmed");
}
}
Now the question is: I don't know how can I set the emailConfirmed
variable of EmailConfirmed
component to true from WEB API and in the return Redirect
line, in order the user see the second message this time? Also I doubt that I have chosen the best way to redirect the application to an Angular route using the return Redirect("http://localhost:5000/emailconfirmed");
line.
3 Answers 3
@ManojChoudhari is right. You can't route like this!
First it should be a "HttpPost". Return a response and then redirect on the clientside using router. Here is a little example. This does not take into account the separation of concerns!
Serverside
Models
public class UserRequest {
public string UserId { get; set; }
public string Code { get; set; }
}
public class EMailConfirmationResponse {
public boolean EmailConfirmed { get; set; }
}
Controller
...
[HttpPost]
[Route("ConfirmEmail", Name = "ConfirmEmailRoute")]
public async Task<IHttpActionResult> ConfirmEmail(UserRequest user)
{
var result = await UserManager.ConfirmEmailAsync(user.UserId, user.Code)
if (result.Succeeded)
{
return Ok(new EMailConfirmationResponse { EmailConfirmed = true });
}
else
{
return BadRequest("An error occurred confirming the given email-address.");
}
}
...
Clientside
import { Component } from "@angular/core";
import { Router } from "@angular/router";
import { HttpClient } from "@angular/common/http";
@Component({
selector: "your",
templateUrl: "./your.component.html"
})
export class YourAngularComponent {
constructor(
private _router: Router,
private _http: Http
) {
...
// put this into your method
const httpOptions = { headers: new HttpHeaders({'Content-Type': 'application/json', 'Authorization': 'my-auth-token'}) };
this.http
.post("webapiurl", { userId: "TheUserId", code: "TheUserCode" }, httpOptions)
.subscribe((response) => {
const emailConfirmationResponse = response.json();
if(emailConfirmationResponse.emailConfirmed) {
this._router.navigate(["emailconfirmed"]);
}
}, (err: HttpErrorResponse) => {
// do some error handling here:
console.log(err.error);
console.log(err.name);
console.log(err.message);
console.log(err.status);
}
);
...
-
Thanks. Could you please show me also the client-side part? What I need to do in the client?user5032790– user50327902019年05月02日 09:44:46 +00:00Commented May 2, 2019 at 9:44
-
thanks @Pierre. I was about to type this same example. Thanks for adding it.Manoj Choudhari– Manoj Choudhari2019年05月02日 09:46:27 +00:00Commented May 2, 2019 at 9:46
-
1So you mean I should change the CallbackURL that I send as an Email to user to point to an angular route instead and then I call an HttpPost from angular component to my API to enable the confirm property and then use the result?user5032790– user50327902019年05月02日 18:06:18 +00:00Commented May 2, 2019 at 18:06
One thing you need to understand is - the Angular routes are only available on client side. You will not be able to redirect user to angular template from server side.
The option you have probably is to return some flag from web API. This flag should be unique and then angular should redirect user to other page.
Your API Code should be:
[HttpGet]
[Route("ConfirmEmail", Name = "ConfirmEmailRoute")]
public async Task<IActionResult> ConfirmEmail(string userId = "", string code = "")
{
//....
IdentityResult result = await UserManager.ConfirmEmailAsync(userId, code);
if (result.Succeeded)
{
return Ok();
}
else
{
return BadRequest("An error occurred confirming the given email-address.");
}
}
In your client side typescript you can add below code:
//// result = call web api and take result
//// if result is 200 OK then
this.router.navigate(['/your-path'])
Hope this helps.
-
Thanks. Would you please show me an example of how can I do this? I am new to Angular and don't have any idea what I need to do to achieve what you said.user5032790– user50327902019年05月02日 08:59:50 +00:00Commented May 2, 2019 at 8:59
-
@J.P - does this link help ?Manoj Choudhari– Manoj Choudhari2019年05月02日 09:05:43 +00:00Commented May 2, 2019 at 9:05
-
No. I checked the link but I think It is different from mine.user5032790– user50327902019年05月02日 09:08:32 +00:00Commented May 2, 2019 at 9:08
-
I need to find a way to set the
emailConfirmed
to true after Email is confirmed.user5032790– user50327902019年05月02日 09:10:39 +00:00Commented May 2, 2019 at 9:10 -
Did you try making ajax call and returning bool from web api ? on client side, then you can direct to new page using angular route to other page.Manoj Choudhari– Manoj Choudhari2019年05月02日 09:13:08 +00:00Commented May 2, 2019 at 9:13
I guess directly from webapi you can't redirect. use Api response and then in angular redirect to another page or domain.