2

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.

asked May 2, 2019 at 8:34

3 Answers 3

2

@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);
 }
 );
...
answered May 2, 2019 at 9:32
3
  • Thanks. Could you please show me also the client-side part? What I need to do in the client? Commented May 2, 2019 at 9:44
  • thanks @Pierre. I was about to type this same example. Thanks for adding it. Commented May 2, 2019 at 9:46
  • 1
    So 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? Commented May 2, 2019 at 18:06
1

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.

answered May 2, 2019 at 8:58
10
  • 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. Commented May 2, 2019 at 8:59
  • @J.P - does this link help ? Commented May 2, 2019 at 9:05
  • No. I checked the link but I think It is different from mine. Commented May 2, 2019 at 9:08
  • I need to find a way to set the emailConfirmed to true after Email is confirmed. Commented 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. Commented May 2, 2019 at 9:13
0

I guess directly from webapi you can't redirect. use Api response and then in angular redirect to another page or domain.

answered May 2, 2019 at 12:57

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.