2

I am trying to load data from my web api controller. Currently I am using my API service which I call from the ngOnInit function of the component. But, nothing return in the view because it's an asynchronous data

Web api controller

[HttpGet("[action]")]
    public async Task<UserModel> GetUserById(int id)
    {
        Response.StatusCode = 200;
        try
        {
            _context = new AuthentificationDbContext();
            UserModel user = await _context.User.SingleOrDefaultAsync(m => m.id == id);
            if (user == null)
            {
                return null;
            }
            else
              return (user);
        }
        catch (SqlException ex)
        {
            throw ex;

        }
    }

userService.ts

getUserId(id: number) : Observable<User>{
    return this.http.get(this.url + 'userApi/GetUserById/?id=' + id)
        .map(res => <User>res.json())
        .catch(this.handleError);
}

app.routing.ts

{ path: 'user/:id', component: UserComponent}
export const routing = RouterModule.forRoot(appRoutes,{ 
                                            enableTracing:true});
export const routedComponents = [UserComponent];

user.component.ts

export class UserComponent implements OnInit {
private user: User;
constructor(private userService: UserService, private route: ActivatedRoute, private router: Router) { }

    ngOnInit() {  
           this.route.paramMap
                    .switchMap((params: ParamMap) =>
                        this.userService.getUserId(+params.get('id')))
                    .subscribe((user: User) => {
                        this.user = user;
                    });

    }

}

user.cshtml

<div *ngIf="user">{{ user.name}}</div>

But, when I tried with that example, that's work because not asynchronous

import { Injectable, Inject } from '@angular/core';
import { Http, Response, RequestOptions, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
export class User {
constructor(public id: number, public name: string) { }
}
let Users = [
new User(11, 'Mr. Nice'),
new User(12, 'Narco')
];
let usersPromise = Promise.resolve(Users);
@Injectable()
export class UserService {
constructor( @Inject(Http) public http: Http) { }

    getUserId(id: number | string) {
        return usersPromise
            .then(users => users.find(user => user.id === +id));
    }

}

My question : how to load async data in ngOnInit? I used by promise also, but doesn't work

  • .subscribe((user: User) => { this.user = user; here did you try console.log(this.user) to check what data you have received? – Dheeraj Kumar Sep 11 '17 at 10:19
  • 1
    Please add the code that shows how you use `user` in the view. Even if your code is async, it still sets `this.user` (if `this.userService.getUserId(+params.get('id'))` is valid code and eventually a response arrives. Your code might break if you depend on the result being available immediately, but that's hard to tell without seeing the code. – Günter Zöchbauer Sep 11 '17 at 10:19
  • Yes, I'm using by console.log(this.user) but the problem is about async data in web api controller. I tried with another example, that's work export class User { constructor(public id: number, public name: string) { } let Users = [ new User(11, 'Mr. Nice'), new User(12, 'Narco')]; let usersPromise = Promise.resolve(Users); getUserId(id: number | string) { return usersPromise.then(users => users.find(user => user.id=== +id)); } } – Noura Messaoudi Sep 11 '17 at 10:52
  • The code in the view

    {{ user.name}}

    – Noura Messaoudi Sep 11 '17 at 10:54
  • Code in comments is quite hard to read, please edit your question and add the code there. – Günter Zöchbauer Sep 11 '17 at 11:12
  • That's ok, now the question has updated – Noura Messaoudi Sep 11 '17 at 12:19

2 Answers2

0

If you use

{{user.view}}

in the components template, you'll get an error, because user isn't available immediately.

{{user?.view}}

(safe-nativation operator) avoids this error by not throwing an exception when user is null.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Thanks Günter, I know the problem is with user isn't available immediately. My question is how to load async data in ngOnInit? – Noura Messaoudi Sep 11 '17 at 11:00
  • Your code is already loading data async. Have you even tried my suggestion? Have you checked if you get an error? – Günter Zöchbauer Sep 11 '17 at 11:11
  • I tried with your suggestion, but doesn't work I execute my code with debugger and I put a stop, but the debugger does not execute the function in web api controller, just execute userService.ts – Noura Messaoudi Sep 11 '17 at 12:49
  • What exactly is "the function"? – Günter Zöchbauer Sep 11 '17 at 12:55
  • public async Task GetUserById(int id) – Noura Messaoudi Sep 11 '17 at 13:00
  • Please, can you give me an example explain how to get async data in ngOnInit from web api controller – Noura Messaoudi Sep 11 '17 at 13:10
  • I don't know what you ask for. There is no difference whether you try to get async data it in `ngOnInit()` or elsewhere. Perhaps your async code is invalid, but the problem is not related to `ngOnInit` – Günter Zöchbauer Sep 11 '17 at 13:13
  • 1
    Ok, thanks Günter, I think the problem is related to routing with parameters because I tried by many examples without parameters and no problem. I'm beginner in angular 4 and there is my first example from routing with parameter, just time and I will resolve it. – Noura Messaoudi Sep 11 '17 at 13:31
0

I can resolve my problem (it's related to routing) : my code just need to insert this :

<script>document.write('<base href="' + document.location + '" />');</script>

at the top of the 'head' section.


And to insert in constructor from app.component.ts, this methode:

click() {
    this.router.navigate(['', { foo: 'bar' }]);
}