1

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.

Laura
  • 97
  • 9
  • to explain in simple terms, code inside `subscribe` is executed asynchronously. which means when the execution reaches second `console.log` statement, the code inside `subscribe` has not been executed yet. the reason is that it gets executed whenever your http call completes and program doesn't know when it will happen, that's why it is executed asynchronously. put your second `console.log` into subscribe block and you will get correct results. but i think you are trying to use `roles` synchronously somewhere else and this will not remedy your actual problem. so what r u actually trying to do? – ysf Jun 28 '19 at 08:41
  • Thanks Sir @ysf for your reply. But I need that object outside subscribe, that what actually trying to do. – Laura Jun 28 '19 at 08:52
  • I need `roles` to fill checklist and that will done outside subscribe. – Laura Jun 28 '19 at 09:04
  • please share the code for filling the checklist. – ysf Jun 28 '19 at 09:09

4 Answers4

4

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

Saria Essid
  • 1,240
  • 1
  • 11
  • 16
1

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();
}
LeBavarois
  • 938
  • 2
  • 11
  • 24
  • Hello Sir @LeBavarois, Thanks a lot for your reply. But I got this error `'await' expression is only allowed within an async function`. – Laura Jun 28 '19 at 09:23
  • You need to add the keyword `async` to the function within which you use `await`. – LeBavarois Jun 28 '19 at 09:29
  • I got `Cannot find name 'async'` when I tried with `async await this.userService.getAllRolesOfActualUser(user.id).then(listRoles =>` – Laura Jun 28 '19 at 09:40
  • Okay, maybe my comment was bit unclear. The function that is using await in its body has to have the async keyword.Assuming you want to get the roles when a users is selected, your code could look like this: `async onUserSelected(User user) { await this.userService.getAllRolesOfActualUser(user.id); // an so on }` – LeBavarois Jun 28 '19 at 09:50
1

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);
   });
 }
Chanaka Weerasinghe
  • 5,404
  • 2
  • 26
  • 39
  • Hello Sir, thanks a lot for your reply. But, I got `Property 'then' doesn't not exist on type Subscription` – Laura Jun 28 '19 at 09:38
  • Hello Sir @ORBIT, thanks a lot for your reply. I made the method `getData()` on my controller. and I called it on **ngOnInit()**, `this.getData().then(data => { console.log("++++++++++++++++++++++" + data); })` but I got any thing, the console isn't shown – Laura Jun 28 '19 at 10:06
  • UPDATED CODE CHECK – Chanaka Weerasinghe Jun 28 '19 at 10:16
  • Hu Sir, I did that, but the console produces: `Object { __zone_symbol__state: null, __zone_symbol__value: [] } ` and `[object Promise] ` on **ngOnInit()** – Laura Jun 28 '19 at 11:22
  • Hello Sir, I got anything on console when I call `this.doAsyncTask().then( (value) => console.log(value), (error) => console.error(error) );` on **ngOnInit()**. However I got correct result on the function. – Laura Jun 28 '19 at 12:20
  • Good if it helped – Chanaka Weerasinghe Jun 28 '19 at 13:33
  • Thanks Sir, But I don't get anything on **ngOnInit()**, Have you please any idea on how can I resolve this problem ?. Thanks. – Laura Jun 28 '19 at 13:38
0

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.

Emmanuel Ani
  • 432
  • 5
  • 10