Как обрабатывать асинхронные данные в ngOnInit (маршрутизация с параметром) Angular 4

Я пытаюсь загрузить данные с моего контроллера веб-API. В настоящее время я использую свою службу API, которую я вызываю из функции ngOnInit компонента. Но в представлении ничего не возвращается, потому что это асинхронные данные.

Контроллер веб-API

[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>

Но когда я попробовал этот пример, это сработало, потому что не асинхронно

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));
    }

}

Мой вопрос: как загрузить асинхронные данные в ngOnInit? Я также использовал обещание, но не работает


person Noura Messaoudi    schedule 11.09.2017    source источник
comment
.subscribe((user: User) => { this.user = user; здесь вы пробовали console.log(this.user) проверить, какие данные вы получили?   -  person Dheeraj Kumar    schedule 11.09.2017
comment
Добавьте код, показывающий, как вы используете user в представлении. Даже если ваш код является асинхронным, он все равно устанавливает this.user (если this.userService.getUserId(+params.get('id')) является действительным кодом и в конечном итоге приходит ответ. Ваш код может сломаться, если вы зависите от немедленной доступности результата, но это трудно сказать, не видя кода.   -  person Günter Zöchbauer    schedule 11.09.2017
comment
Да, я использую console.log(this.user), но проблема связана с асинхронными данными в контроллере веб-API. Я попробовал другой пример, это рабочий экспортный класс User {structor(public id: number, public name: string) {} let Users = [ new User(11, 'Mr. Nice'), new User(12, 'Narco' )]; пусть usersPromise = Promise.resolve(Пользователи); getUserId(id: number | string) { return usersPromise.then(users=>users.find(user=>user.id=== +id)); } }   -  person Noura Messaoudi    schedule 11.09.2017
comment
Код в представлении ‹div *ngIf=user› ‹h3›{{ user.name}}‹/h3› ‹/div›   -  person Noura Messaoudi    schedule 11.09.2017
comment
Код в комментариях довольно сложно прочитать, пожалуйста, отредактируйте свой вопрос и добавьте туда код.   -  person Günter Zöchbauer    schedule 11.09.2017
comment
Все в порядке, теперь вопрос обновлен   -  person Noura Messaoudi    schedule 11.09.2017


Ответы (2)


Если вы используете

{{user.view}}

в шаблоне компонентов вы получите сообщение об ошибке, потому что user недоступно сразу.

{{user?.view}}

(оператор безопасной активации) позволяет избежать этой ошибки, не вызывая исключения, когда user имеет значение null.

person Günter Zöchbauer    schedule 11.09.2017
comment
Спасибо, Гюнтер, я знаю, что проблема в том, что пользователь недоступен сразу. Мой вопрос: как загрузить асинхронные данные в ngOnInit? - person Noura Messaoudi; 11.09.2017
comment
Ваш код уже загружает данные асинхронно. Вы хоть пробовали мое предложение? Вы проверили, если вы получаете ошибку? - person Günter Zöchbauer; 11.09.2017
comment
Я попытался с вашим предложением, но не работает. Я выполняю свой код с помощью отладчика и останавливаю, но отладчик не выполняет функцию в контроллере веб-API, просто выполняю userService.ts - person Noura Messaoudi; 11.09.2017
comment
Какая именно функция? - person Günter Zöchbauer; 11.09.2017
comment
общедоступная асинхронная задача‹UserModel› GetUserById (int id) - person Noura Messaoudi; 11.09.2017
comment
Пожалуйста, не могли бы вы привести пример, объясняющий, как получить асинхронные данные в ngOnInit из контроллера веб-API. - person Noura Messaoudi; 11.09.2017
comment
Я не знаю, о чем вы просите. Нет никакой разницы, пытаетесь ли вы получить асинхронные данные в ngOnInit() или в другом месте. Возможно, ваш асинхронный код недействителен, но проблема не связана с ngOnInit - person Günter Zöchbauer; 11.09.2017
comment
Хорошо, спасибо, Гюнтер, я думаю, проблема связана с маршрутизацией с параметрами, потому что я пробовал много примеров без параметров и без проблем. Я новичок в angular 4, и есть мой первый пример маршрутизации с параметром, просто время, и я его решу. - person Noura Messaoudi; 11.09.2017

Я могу решить свою проблему (это связано с маршрутизацией): мой код просто должен вставить это:

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

в верхней части раздела «голова».


И вставить в конструктор из app.component.ts этот метод:

click() {
    this.router.navigate(['', { foo: 'bar' }]);
}
person Noura Messaoudi    schedule 12.09.2017