Angular: Почему http-вызов будет работать в ngOnInit, а не в событии click? (Что-то связанное с кешированием) - PullRequest
1 голос
/ 11 июня 2019

В моем угловом приложении я настроил простой сервис для звонков на сервер.и я ввел сервис в компонент.Если я вызываю один из его методов непосредственно в методе компонента ngOnInit (), он работает нормально, и ожидаемый ответ получен от серверной части.Если я вызываю тот же метод обслуживания, нажимая кнопку в компоненте, я получаю http ошибку в журнале консоли:

VM460:1 GET https://myurl/getUserNumber net::ERR_FAILED
   message: "Http failure response for https://myurl/getUserNumber: 0 Unknown Error"
   {
      ...
      name: "HttpErrorResponse"
      ok: false
      status: 0
      statusText: "Unknown Error"
   }

Если я правильно понимаю, проблема в том, что серверу не нравится запросили что-то типа того.Но в чем разница между первым и вторым http-вызовом?Что мне не хватает?Спасибо!

// service method
getUserNumber(): Observable<User> {
    return this.http.get<User>(url.getUserNumber);
}

// component
export class DataComponent implements OnInit {

    private userNumber$ = new BehaviorSubject<string>('');

    constructor(private dataService: DataService) {}

    ngOnInit() {
        this.dataService.getUserNumber()
            .subscribe( (user: User) => this.userNumber$.next(user.number));
    }

    getUserNumber(): void {
        this.dataService.getUserNumber()
            .subscribe( (user: User) => this.userNumber$.next(user.number));
    }
}

 <!-- button to call the service method from template which is not working -->
 <button (click)="getUserNumber()">GET</button>

ОБНОВЛЕНИЕ 1: Я не думаю проблема связана с Cors - приложение можно просмотреть на myurl.com и http-вызовы переходят на myurl.com / getwhwhat .Я обновляю существующее приложение, которое делает запросы AJAX, с помощью jQuery, и я использую ту же среду / настройки и т. Д., Только с Angular вместо JQuery - ничто другое не отличается (насколько я вижу).

Чтобы попытаться максимально приблизить все к основам, я сделал новое угловое приложение с очень простым сервисом, который вызывается из app.component.ts, как показано ниже.ngOnInit() работает нормально, отображаются время и информация о пользователе.Нажатие кнопки для getTime() работает и обновляет экран, нажатие кнопки для getUserNumber() как обычно не работает.(время - просто посмотреть, смогу ли я найти что-то в Observables, которое мне не хватало, с удаленной частью http ... Мне не слишком жарко с rxjs)

Полный список выхода из системы здесь: https://pastebin.com/v6SmzHnn

Сведения об ошибке здесь: https://pastebin.com/FkxF58ea

app.component.ts

export class AppComponent implements OnInit{

    user$: Observable<{}>;
    time$: Observable<string>;

    constructor(private api: ApiService) {}

    ngOnInit(): void {
        this.getTime();
        this.getUserNumber();
    }

    getUserNumber(): void {
        this.user$ = this.api.getUserNumber();
    }

    getTime(): void {
        this.time$ = this.api.getTime();
    }

}

API.service.ts

export class ApiService {

    constructor(private http: HttpClient) { }

    public getUserNumber(): Observable<{}> {
        return this.http.get<{}>(url.getUserNumber);
    }

    public getTime(): Observable<string> {
        const today = new Date();
        const time = today.getHours() + ':' + today.getMinutes() + ':' + today.getSeconds();
        return of(time);
    }
}

шаблон

<code><button (click)="getUser()">Get User</button>
<button (click)="getTime()">Get time</button>

<div>{{ time$ | async }}</div>
<div><pre>{{ (user$ | async) | json }}

ОБНОВЛЕНИЕ 2: Я использую файл манифестакэшировать приложение для автономного использования - похоже, это является источником проблемы - нет ошибок, если манифест не включен.В старом приложении jquery также используется манифест, поэтому я не уверен, почему он ломается под углом, но, по крайней мере, я могу забыть о rxjs, cors и т. Д ...

1 Ответ

1 голос
/ 11 июня 2019

Вы звоните подписываться каждый раз, когда вы нажимаете.Это новая подписка, а старая еще "горячая".Попробуйте использовать take, чтобы правильно выполнить калибровку и завершить сабвуфер.В противном случае у вас будет х число подписок.

getUserNumber(): void {
    this.dataService.getUserNumber().pipe(
       take(1)
    ).subscribe( (user: User) => {
       console.log(user); // make sure you're getting a response from dataService
       this.userNumber$.next(user.number)
    });
}

Кроме того, сделайте вызов getUserNumber() в ngOnInit, чтобы у вас не было 2 подписок.(передовой опыт + облегчает поиск неисправностей)

public ngOnInit() {
    this.getUserNumber();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...