У меня проблема с вызовом веб-сервиса с помощью 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
в первый раз, а во второй раз нет?
РЕДАКТИРОВАТЬ :
на моем компоненте я пробую это сейчас, но не работаю:
и на моей службе:
Это асинхронное поведение!
Как я могу это исправить?
Возможный дубликат Как вернуть ответ на асинхронный вызов?
HttpClient причина Http устарела
@GiovanniD'Amico На самом деле это зависит! Например: если вы хотите использовать это значение, используйте if (value)
@GiovanniD'Amico Если вы хотите получить объяснение о why this happens
, опубликуйте повторяющийся вопрос. Или, если вы столкнулись с какой-либо проблемой, обновите вопрос в соответствии с этим!
Нет, мне нужно решение, потому что я не могу его найти
@GiovanniD'Amicoc проверьте пользовательский интерфейс, если данные существуют, чем показать или использовать другой вариант setTimeout
.
Я думаю, что установить тайм-аут или сделать цикл не лучший способ сделать вызов синхронизации
Я считаю, что вы вызвали состояние гонки. Когда вы впервые регистрируете пользователя, он еще не возвращен службой. Вместо этого вы можете зарегистрировать его следующим образом:
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" и второй раз, когда мой результат
Куда звонить credenzialiConfronto
?
На кнопке отправки на моей странице входа
У вас есть один console.info
внутри функции tap
, и он все еще возвращает undefined
?
Внутри коснитесь его, вернитесь: pipe[object Object]. Внешний возврат "undefined"
Это связано с тем, что javascript является asynchronous
, поэтому он не будет ждать завершения вызова API.
В своем коде вы регистрируете User
вне области действия подписки, если вы входите в подписку, вы получите данные user
при первом вызове.
В вашем коде нет ничего плохого.
Для синхронизации javascript вы можете реализовать async
await
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 я асинхронный, но я пытаюсь использовать подписку, чтобы синхронизировать его. Как я могу это исправить?
Хорошо, для этого вы можете реализовать async
await
в вашем коде нет ничего плохого. я покажу вам, как реализовать async
await
.
async и await не работают. Что я могу сделать? Где моя ошибка?
есть ли ошибка? Можете ли вы показать мне, что вы сделали до сих пор.
В вашей credenzialiConfronto
функции ваш тип возвращаемого значения не promise
проверьте мой ответ в моем ответе credenzialiConfronto
тип возвращаемого значения — обещание, а внутри подписки я пишу resolve
.
resolve
означает, что успешный обратный вызов означает возврат true
.
Если мои ответы помогут вам, примите это, чтобы другие люди получили от этого помощь.
Человек это работает так хорошо. Большое спасибо! Можете ли вы объяснить мне, почему?
Метод Promise.resolve() возвращает объект Promise, разрешенный с заданным значением. Если значение является обещанием, возвращается это обещание; если значение является доступным (т. е. имеет метод «тогда»), возвращенное обещание «последует» за этим доступным, приняв его конечное состояние; в противном случае возвращенное обещание будет выполнено со значением. Эта функция объединяет вложенные слои объектов, подобных обещаниям (например, обещание, которое разрешается в обещание, которое разрешается во что-то) в один слой.
согласно это
это должно быть твоей услугой
/** 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);
});
Это дает мне тот же результат
Потому что по умолчанию инициализация переменной
User
с неопределенным значением. и вызов API требует некоторого времени для получения данных.