У меня есть функция login(), которая вызывает запрос HTTP POST для генерации SID. Когда функция завершается, я применяю ее к локальной переменной с именем this.sid. Когда я вызываю функцию Login(), я ожидаю, что переменная thid.sid будет содержать значение SID, но вместо этого я получаю неопределенное значение.
sid: string | undefined;
login() {
const body = `<soapenv:Envelope xmlns:soapenv = "http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser = "http://www.ca.com/UnicenterServicePlus/ServiceDesk">
<soapenv:Header/>
<soapenv:Body>
<ser:login>
<username>servicedesk</username>
<password>?</password>
</ser:login>
</soapenv:Body>
</soapenv:Envelope>`
this.http
.post(this.soapURL, body, {
headers: {
'SOAPAction': '""',
'Content-Type': 'text/xml;charset=UTF-8'
},
responseType: 'text'
})
.subscribe({
next: (res) => {
const parser = new xml2js.Parser({ strict: false, trim: true });
parser.parseString(res, (err, result) => {
this.soapenvEnvelope = result;
this.sid = this.soapenvEnvelope?.["SOAPENV:ENVELOPE"]["SOAPENV:BODY"][0].LOGINRESPONSE[0].LOGINRETURN[0]._;
});
console.info(this.sid )
},
error: (ex) => {
console.info(ex)
}
})
}
foo() {
this.login()
console.info(this.sid) // undefined
}
Код внутри подписки является асинхронным (ждет завершения API). Код после вызова входа в систему является синхронным (не ждет завершения API), поэтому вы получаете эту проблему. Чтобы решить эту проблему, вы можете просто переместить свой код внутри подписки, чтобы код выполнялся последовательно.
Чтобы узнать больше, я рекомендую это Что такое цикл событий, который помог мне научиться.
.subscribe({
next: (res) => {
const parser = new xml2js.Parser({ strict: false, trim: true });
parser.parseString(res, (err, result) => {
this.soapenvEnvelope = result;
this.sid = this.soapenvEnvelope?.["SOAPENV:ENVELOPE"]["SOAPENV:BODY"][0].LOGINRESPONSE[0].LOGINRETURN[0]._;
});
console.info(this.sid )
// move your code here and execute inside the subscribe.
},
error: (ex) => {
console.info(ex)
}
})
@elhanan проголосуй за (^
), если ответ поможет, спасибо!
Этот вопрос похож на: Как мне вернуть ответ от вызова Observable/http/async в angular?. Если вы считаете, что это другое, отредактируйте вопрос, поясните, чем он отличается и/или как ответы на этот вопрос не помогают решить вашу проблему.