Cannot get synchronization from inside subscribe to outside subscribe using localStorage or sessionStorage

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-11 07:49:16

问题


I have this mapping:

User     *----------------------------1     Role

From the list of users, I go to consult one user from this list. To get some informations about that selected user, I need to use localSorage to get an object from inside subscribe to outside subscribe.

Bellow is the method:

this.userService.getAllRolesOfActualUser(user.id).subscribe(listRoles =>
{

     let roles:Array<Role> = [];

     if (listRoles)
     {
         listRoles.forEach((role) =>
         {
             roles.push(new Role(role.id, role.name, role.selected));
         });
     }

     sessionStorage.removeItem("roles");
     sessionStorage.setItem("roles", JSON.stringify(roles));
     console.log("1. Inside Subscribe- " + user.id + "--------------: " + 
     sessionStorage.getItem("roles"));

});

console.log("2. Outside Subscribe- " + user.id + "--------------: " + sessionStorage.getItem("roles"));

On user.service.ts, I have:

getAllRolesOfActualUser(id: number): Observable<any>
    {
        return this.http.get(`${this.baseUrl}/users/roles/${id}`);
    }

My problem is that usually I got the value of the previous consulted user not the actual user a described by this screenshot:

Could you please help me solving that issue ?!. Big thanks.


回答1:


You have to use promise:

    ses : String[];
    expertises : String[] = [];

    async getUri(userId: number)
        {
            let affected = this.userService.getExpertisesListByIdUserPromise(userId);

            await affected.then((uri) =>
            {
                this.ses = uri;
            })

            return this.ses;
        }

and on ngOnInit, I have

this.getUri(16).then(item => 
        {
            item.forEach(pro=>
            {
                this.expertises.push(pro);
            });
        });

on the service file, you have:

getExpertisesListByIdUserPromise(id: number): Promise<any>
    {
        return this.http.get(`${this.baseUrl}/users/expertises/${id}`).toPromise();
    }

HTH




回答2:


I am not sure what you actually want to achieve, but if you want to the result "outside the subscribe" directly below in your example, you will probably have to run your code in a more synchronous way.

For example you could use a Promise instead of an Observable and await the execution:

await this.userService.getAllRolesOfActualUser(user.id).then(listRoles =>
{

 let roles:Array<Role> = [];

 if (listRoles)
 {
     listRoles.forEach((role) =>
     {
         roles.push(new Role(role.id, role.name, role.selected));
     });
 }

 sessionStorage.removeItem("roles");
 sessionStorage.setItem("roles", JSON.stringify(roles));
 console.log("1. Inside Subscribe- " + user.id + "--------------: " + 
 sessionStorage.getItem("roles"));

});

console.log("2. Outside Subscribe- " + user.id + "--------------: " + sessionStorage.getItem("roles"));

And in your service:

getAllRolesOfActualUser(id: number): Promise<any>
{
    return this.http.get(`${this.baseUrl}/users/roles/${id}`).toPromise();
}



回答3:


source So you have to work with Promise:

      getData(){
            var promiseData =return new Promise((resolve, reject) => {
              this.userService.getAllRolesOfActualUser(user.id).subscribe('........')
                    .subscribe(
                     data => {

    //your handlings
                      resolve(data)
                    },
                     error => {
                      reject(error);
                    },
            );
                });
return promiseData;
        }

And in your controller:

getData().then(data => {
      console.log(data);
//do here what you want
    })

if you figer it out simply test this and check

doAsyncTask() {
  let error = true;
   return new Promise((resolve, reject) => {
     setTimeout(() => {
       if (error) {
         reject('error'); // pass values
       } else {
         resolve('done'); // pass values
       }
     }, 1000);
   });
 }

 this.doAsyncTask().then(
  (val) => console.log(val),
  (err) => console.error(err)
);

********* My Edit according to your proposition

doAsyncTask() {
  let error = true;
   return new Promise((resolve, reject) => {
     setTimeout(() => {
       if (error) {
         reject('error'); // pass values
       } else {
         this.userService.getExpertisesListByIdUserObj(2)
                // .subscribe('........')
                .subscribe(listExpertises =>
                      {
                        console.log("YES");
                          let exps:Array<Expertise> = [];

                          if (listExpertises)
                          {
                              listExpertises.forEach((expert) =>
                              {
                                  exps.push(new Expertise(expert.id, expert.name, expert.selected));
                              });
                          }

                          sessionStorage.removeItem("exps");
                          sessionStorage.setItem("exps", JSON.stringify(exps));
                          console.log("1. MODIF-IN " + 2 + "--------------: " + sessionStorage.getItem("exps"));

              });
         resolve('done'); // pass values
       }
     }, 1000);
   });
 }



回答4:


From your user.service.ts you are getting just one object from your pool of objects (Array of Objects) and in your component.ts You are saving your payload as a stringified object so to get the desired result you need to convert it back to JSON by doing

let role = sessionStorage.getItem('roles');
let rolesObject = JSON.parse('role')

console.log("1. LIST- " + user.id + "--------------: " +  rolesObject;

I don't know why you are doing the array.push but i think you should just go with the payload in your listRoles.



来源:https://stackoverflow.com/questions/56803439/cannot-get-synchronization-from-inside-subscribe-to-outside-subscribe-using-loca

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!