我有将用户令牌传递给服务器并将结果返回给组件的服务,但是当我的令牌存在时,它将不断返回token: undefined
。
注意:我对每个部分都进行了评论,以更好地理解。
Service
export class GroupsService {
token: any;
constructor(
private storageIonic: NativeStorage,
private env: EnvService,
private http: HttpClient,
) {
// Get token
this.storageIonic.getItem('token').then((token) => {
this.token = token.access_token;
}).catch(error => console.error(error));
}
getGroups(): Observable<any> {
// I also add this here to make sure that i will get token in any case, yet it's returning undefined
if (this.token === undefined) {
this.storageIonic.getItem('token').then((token) => {
this.token = token.access_token;
}).catch(error => console.error(error));
}
console.log('token: ', this.token); // undefined
const httpOptions = {
headers: new HttpHeaders({
Authorization : this.token, //sending token to server
Accept: 'application/json, text/plain',
'Content-Type': 'application/json'
})
};
return this.http.get(`${this.env.GROUPS}`, httpOptions).pipe(
map(groups => groups)
);
}
}
Component
export class Tab1Page implements OnInit {
groups: any[] = [];
groupsOpts = {
loop: false,
slidesPerView: 3,
slidesPerColumn: 2
};
constructor(
private groupsService: GroupsService,
private menu: MenuController,
) {
this.menu.enable(true);
this.getGroups();
}
ngOnInit() {
//
}
// I added async/await yet result hasn't change.
async getGroups() {
await this.groupsService.getGroups().subscribe((res) => {
console.log('res: ', res);
console.log('res data: ', res.data);
console.log('res data data: ', res.data.data);
for (const group of res.data) {
this.groups.push(group);
}
});
}
}
您知道如何解决此问题吗?
答案 0 :(得分:1)
您可以使用switchMap
来传递令牌承诺数据。
import { from } from "rxjs";
export class GroupsService {
token: any;
getGroups(): Observable<any> {
// I also add this here to make sure that i will get token in any case, yet it's returning undefined
const tokenPromise =
this.token === undefined
? this.storageIonic.getItem("token")
: Promise.resolve(this.token);
return from(tokenPromise).pipe(
switchMap((token) => {
this.token = token;
const httpOptions = {
headers: new HttpHeaders({
Authorization: this.token, //sending token to server
Accept: "application/json, text/plain",
"Content-Type": "application/json",
}),
};
return this.http
.get(`${this.env.GROUPS}`, httpOptions)
.pipe(map((groups) => groups));
})
);
}
}
答案 1 :(得分:0)
this.storageIonic.getItem('token').then((token) => {
this.token = token.access_token;
}).catch(error => console.error(error));
}
此呼叫是异步的,您不会在下一行获得令牌 像这样尝试
export class GroupsService {
token: any;
constructor(
private storageIonic: NativeStorage,
private env: EnvService,
private http: HttpClient,
) {
// Get token
this.storageIonic.getItem('token').then((token) => {
this.token = token.access_token;
}).catch(error => console.error(error));
}
getGroups(): Observable < any > {
// I also add this here to make sure that i will get token in any case, yet it's returning undefined
let response = new Observable<any>();
if (this.token === undefined) {
this.storageIonic.getItem('token').then((token) => {
this.token = token.access_token;
console.log('token: ', this.token); // undefined
const httpOptions = {
headers: new HttpHeaders({
Authorization: this.token, //sending token to server
Accept: 'application/json, text/plain',
'Content-Type': 'application/json'
})
};
response = this.http.get(`${this.env.GROUPS}`, httpOptions).pipe(
map(groups => groups)
);
}).catch(error => console.error(error));
}
return response;
}
}
答案 2 :(得分:0)
在发出http请求之前,您需要等待promise返回一个值。您可以将令牌逻辑放入返回承诺的自己的函数中,然后使用RxJS from
函数启动可观察对象。一旦承诺返回值,您就可以使用switchMap
发出您的http请求。
我已经将您的map
包含在RxJS管道中,尽管目前它什么也没做。
export class GroupsService {
token: any;
constructor(
private storageIonic: NativeStorage,
private env: EnvService,
private http: HttpClient,
) {
}
getGroups(): Observable<any> {
return from(this.getToken()).pipe(
switchMap(() => {
const httpOptions = {
headers: new HttpHeaders({
Authorization : this.token, //sending token to server
Accept: 'application/json, text/plain',
'Content-Type': 'application/json'
})
};
return this.http.get(`${this.env.GROUPS}`, httpOptions);
}),
map(groups => groups)
);
}
private getToken(): Promise<any> {
if (this.token) {
return new Promise((resolve, reject) => resolve(this.token));
}
return this.storageIonic.getItem('token')
.then((token) => {
this.token = token.access_token;
}).catch(error => console.error(error));
}
}
答案 3 :(得分:0)
我不确定您的问题的根源,但您可能希望像我在评论中所解释的那样将可观测值更改为承诺。
getGroups(): Promise<any> {
// I also add this here to make sure that i will get token in any case, yet it's returning undefined
if (this.token === undefined) {
this.storageIonic.getItem('token').then((token) => {
this.token = token.access_token;
}).catch(error => console.error(error));
}
console.log('token: ', this.token); // undefined
const httpOptions = {
headers: new HttpHeaders({
Authorization : this.token, //sending token to server
Accept: 'application/json, text/plain',
'Content-Type': 'application/json'
})
};
return this.http.get(`${this.env.GROUPS}`, httpOptions).toPromise();
// Also probably the below one works too, you can try to find the proper syntax, it was something like this
return this.http.get(`${this.env.GROUPS}`, httpOptions).pipe(
map(groups => groups)
).toPromise();
}
我更改了一些行。 (更改方法签名,Observable => Promise并添加到Promise()返回行)
您可以调用如下方法。
const response = await getGroups(); // This one will return the response of the request.
If you debug the code you will see that your code will wait here until it gets a response.
// IF YOU DO LIKE BELOW IT WON'T MAKE ANY SENSE
const response = getGroups(); // This will not make the call, it will just return the request object.
// In order to do the operation defined in a promise, you must call it with await prefix.
您可能还需要将上述解决方案应用于代码的其他部分。例如。您正在构造函数下初始化令牌,据我所知,这不是一个好习惯,您可能需要将该初始化移到onInit()下并使onInit函数异步。这样,您可以确保在进行呼叫时已定义令牌,否则在进行请求时可能不会初始化令牌。而且由于您没有等待未定义的代码中的检查,同样的事情将再次发生。 (将storageIonic.getItem(token:string)函数转换为Promise,然后从该函数返回令牌)