Первый раз возвращает undefined, а второй правильный результат, как я могу это исправить?

У меня проблема с вызовом веб-сервиса с помощью Angular 7. Вызов выполняется таким образом на моем сервисе:

getLogin(usr: String, pwd: String) {
    return this.http.post("the url of webservice", { username: usr, password: pwd 
    });
}

и на моем компоненте:

 credenzialiConfronto() {
this.cred.getLogin(this.loginForm.get("username").value, this.loginForm.get("psw").value).subscribe((res => {
  this.User = res;
}));

console.info(this.User);

почему он возвращает undefined в первый раз, а во второй раз нет?

РЕДАКТИРОВАТЬ :

на моем компоненте я пробую это сейчас, но не работаю:

https://imgur.com/a/LJ5o4HW

и на моей службе:

https://imgur.com/gUe3sh5

Потому что по умолчанию инициализация переменной User с неопределенным значением. и вызов API требует некоторого времени для получения данных.

Hardik 27.05.2019 12:20

Это асинхронное поведение!

Prashant Pimpale 27.05.2019 12:25

Как я могу это исправить?

Giovanni D'Amico 27.05.2019 12:26

Возможный дубликат Как вернуть ответ на асинхронный вызов?

StudioTime 27.05.2019 12:26
angular.io/guide/http вы использовали HttpClient или Http?
Palak Jadav 27.05.2019 12:26

HttpClient причина Http устарела

Giovanni D'Amico 27.05.2019 12:27

@GiovanniD'Amico На самом деле это зависит! Например: если вы хотите использовать это значение, используйте if (value)

Prashant Pimpale 27.05.2019 12:28

@GiovanniD'Amico Если вы хотите получить объяснение о why this happens, опубликуйте повторяющийся вопрос. Или, если вы столкнулись с какой-либо проблемой, обновите вопрос в соответствии с этим!

Prashant Pimpale 27.05.2019 12:31

Нет, мне нужно решение, потому что я не могу его найти

Giovanni D'Amico 27.05.2019 12:32

@GiovanniD'Amicoc проверьте пользовательский интерфейс, если данные существуют, чем показать или использовать другой вариант setTimeout.

Abhishek 27.05.2019 12:35

Я думаю, что установить тайм-аут или сделать цикл не лучший способ сделать вызов синхронизации

Giovanni D'Amico 27.05.2019 14:18
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
11
896
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я считаю, что вы вызвали состояние гонки. Когда вы впервые регистрируете пользователя, он еще не возвращен службой. Вместо этого вы можете зарегистрировать его следующим образом:

credenzialiConfronto() {
  this.cred.getLogin(this.loginForm.get("username").value, this.loginForm.get("psw").value)
  .pipe(
    tap(user => console.info(user))
  )
  .subscribe((res => {
    this.User = res;
}));

С этим изменением вы регистрируете пользователя только после возврата вызова getLogin.

Это не работает. Тот же результат, что и раньше. Он возвращает первый раз "undefined" и второй раз, когда мой результат

Giovanni D'Amico 27.05.2019 12:23

Куда звонить credenzialiConfronto?

Dániel Barta 27.05.2019 12:24

На кнопке отправки на моей странице входа

Giovanni D'Amico 27.05.2019 12:25

У вас есть один console.info внутри функции tap, и он все еще возвращает undefined?

Dániel Barta 27.05.2019 12:28

Внутри коснитесь его, вернитесь: pipe[object Object]. Внешний возврат "undefined"

Giovanni D'Amico 27.05.2019 12:34
Ответ принят как подходящий

Это связано с тем, что javascript является asynchronous, поэтому он не будет ждать завершения вызова API. В своем коде вы регистрируете User вне области действия подписки, если вы входите в подписку, вы получите данные user при первом вызове. В вашем коде нет ничего плохого.

Для синхронизации javascript вы можете реализовать asyncawait

async callerFunction() {
   await this.credenzialiConfronto();
   console.info(this.User);
}

credenzialiConfronto() {
return new promise ((resolve, reject) => {
  this.cred.getLogin(this.loginForm.get("username").value, 
   this.loginForm.get("psw").value).subscribe((res => {
   this.User = res;
   resolve();
}));
})

я знаю, что js я асинхронный, но я пытаюсь использовать подписку, чтобы синхронизировать его. Как я могу это исправить?

Giovanni D'Amico 27.05.2019 12:31

Хорошо, для этого вы можете реализовать asyncawait

Yash Rami 27.05.2019 12:32

в вашем коде нет ничего плохого. я покажу вам, как реализовать asyncawait.

Yash Rami 27.05.2019 12:34

async и await не работают. Что я могу сделать? Где моя ошибка?

Giovanni D'Amico 27.05.2019 14:18

есть ли ошибка? Можете ли вы показать мне, что вы сделали до сих пор.

Yash Rami 27.05.2019 14:23

В вашей credenzialiConfronto функции ваш тип возвращаемого значения не promise проверьте мой ответ в моем ответе credenzialiConfronto тип возвращаемого значения — обещание, а внутри подписки я пишу resolve.

Yash Rami 27.05.2019 14:47
resolve означает, что успешный обратный вызов означает возврат true.
Yash Rami 27.05.2019 15:02

Если мои ответы помогут вам, примите это, чтобы другие люди получили от этого помощь.

Yash Rami 27.05.2019 15:02

Человек это работает так хорошо. Большое спасибо! Можете ли вы объяснить мне, почему?

Giovanni D'Amico 27.05.2019 15:09

Метод Promise.resolve() возвращает объект Promise, разрешенный с заданным значением. Если значение является обещанием, возвращается это обещание; если значение является доступным (т. е. имеет метод «тогда»), возвращенное обещание «последует» за этим доступным, приняв его конечное состояние; в противном случае возвращенное обещание будет выполнено со значением. Эта функция объединяет вложенные слои объектов, подобных обещаниям (например, обещание, которое разрешается в обещание, которое разрешается во что-то) в один слой.

Yash Rami 27.05.2019 16:56

согласно это

это должно быть твоей услугой

/** POST: data to the database */
login(email, password) : Observable<any>{
return this._http.post<any>(this.APIURL+`login`, { email:email, password:password})
.pipe(map(user => {
  return user;
}));

}

это должен быть ваш компонент

   this._loginService.login(this.model.email, this.model.password)
  .subscribe(
    data => {
      this.toast.success(data[constants.MESSAGE]);
    },
    error => {
      this.toast.warning(constants.LOGIN_ERROR);
    });

Это дает мне тот же результат

Giovanni D'Amico 27.05.2019 14:17

Другие вопросы по теме