'How to use saved data in Ionic/Angular?

I can only use my variable inside the this.storage.get function.

How do I get this saved data?

tab2.page.html:

  <ion-toolbar>
    <ion-title>
      Stats
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>

<ion-card>
    <ion-card-header>
    Bar Chart
    </ion-card-header>
    <ion-card-content>
    <canvas #barCanvas></canvas>
    </ion-card-content>
</ion-card>

</ion-content>

tab2.page.ts:

import { Chart } from "chart.js";
import { Storage } from '@ionic/storage';

@Component({
  selector: 'app-tab2',
  templateUrl: 'tab2.page.html',
  styleUrls: ['tab2.page.scss']
})
export class Tab2Page implements OnInit {

  constructor(public storage:Storage) {}

  @ViewChild("barCanvas") barCanvas: ElementRef;

  h: any;
  a: any;
  s: any;
  e: any;
  w: any;

  ngOnInit() {

    this.storage.get('happiness').then( (val) => {
       this.h = val;
       console.log(this.h, val)
    })
    this.storage.get('anger').then( (val) => {
       this.a = val;
       console.log(this.a, val)
    })
    this.storage.get('stress').then( (val) => {
       this.s = val;
       console.log(this.s, val)
    })
    this.storage.get('energy').then( (val) => {
       this.e = val;
       console.log(this.e, val)
    })
    this.storage.get('worry').then( (val) => {
       this.w = val;
       console.log(this.w, val)
    })

    console.log(this.h, this.a, this.s, this.e, this.w)

    this.barChart = new Chart(this.barCanvas.nativeElement, {
      type: "bar",
      data: {
        labels: ["Happiness", "Anger", "Stress", "Energy", "Worry"],
        datasets: [
          {
            label: "% out of 100",
            data: [this.h, this.a, this.s, this.e, this.w],
            backgroundColor: [
              "rgba(255, 99, 132, 0.2)",
              "rgba(54, 162, 235, 0.2)",
              "rgba(255, 206, 86, 0.2)",
              "rgba(75, 192, 192, 0.2)",
              "rgba(153, 102, 255, 0.2)"
            ],
            borderColor: [
              "rgba(255,99,132,1)",
              "rgba(54, 162, 235, 1)",
              "rgba(255, 206, 86, 1)",
              "rgba(75, 192, 192, 1)",
              "rgba(153, 102, 255, 1)"
            ],
            borderWidth: 2
          }
        ]
      },
      options: {
        scales: {
          yAxes: [
            {
              ticks: {
                beginAtZero: true,
                stepSize: 20
              }
            }
          ]
        }
      }
    });
  }
}



Solution 1:[1]

get() method of Ionic storage returns a promise. So the call to it is asynchronous. And when you try to use the member variables (this.h and so on) for creating the chart, they haven't been assigned values yet. So you end up using undefined or previous values. There are multiple ways to solve this issue. One quick way would be to use forkJoin(). Try the following

import {Observable} from 'rxjs/Observable';

ngOnInit() {
  Observable.forkJoin(
    {
      happiness: this.storage.get('happiness'),
      anger: this.storage.get('anger'),
      stress: this.storage.get('stress'),
      energy: this.storage.get('energy'),
      worry: this.storage.get('worry')
    }
  )
  .subscribe(result => {
    this.barChart = new Chart(this.barCanvas.nativeElement, {
      type: "bar",
      data: {
        labels: ["Happiness", "Anger", "Stress", "Energy", "Worry"],
        datasets: [
          {
            label: "% out of 100",
            data: [result.happiness, result.anger, result.stress, result.energy, result.worry],
            backgroundColor: [
              "rgba(255, 99, 132, 0.2)",
              "rgba(54, 162, 235, 0.2)",
              "rgba(255, 206, 86, 0.2)",
              "rgba(75, 192, 192, 0.2)",
              "rgba(153, 102, 255, 0.2)"
            ],
            borderColor: [
              "rgba(255,99,132,1)",
              "rgba(54, 162, 235, 1)",
              "rgba(255, 206, 86, 1)",
              "rgba(75, 192, 192, 1)",
              "rgba(153, 102, 255, 1)"
            ],
            borderWidth: 2
          }
        ]
      },
      options: {
        scales: {
          yAxes: [
            {
              ticks: {
                beginAtZero: true,
                stepSize: 20
              }
            }
          ]
        }
      }
    });
  });
}

Solution 2:[2]

Try re-writing your methods such that you only do the barChart when you have iterated across your storage and all values were retrieved.

If I am not mistaked you can use forEach iterator method which will return Promise after all the iterations were completed:

ngOnInit() {

    this.storage.forEach((value, key) => {

        switch(key) {
            case "happiness":
                this.h = value;
                break;
            case "anger":
                this.a = value;
                break;
            case "stress":
                this.s = value;
                break;
            default:
                console.log('no case matched')
                break;
        }

    }).then(() => {

        this.barChart = new Chart(this.barCanvas.nativeElement, {
            type: "bar",
            data: {
              labels: ["Happiness", "Anger", "Stress", "Energy", "Worry"],
              datasets: [
                {
                  label: "% out of 100",
                  data: [this.h, this.a, this.s, this.e, this.w],
                  backgroundColor: [
                    "rgba(255, 99, 132, 0.2)",
                    "rgba(54, 162, 235, 0.2)",
                    "rgba(255, 206, 86, 0.2)",
                    "rgba(75, 192, 192, 0.2)",
                    "rgba(153, 102, 255, 0.2)"
                  ],
                  borderColor: [
                    "rgba(255,99,132,1)",
                    "rgba(54, 162, 235, 1)",
                    "rgba(255, 206, 86, 1)",
                    "rgba(75, 192, 192, 1)",
                    "rgba(153, 102, 255, 1)"
                  ],
                  borderWidth: 2
                }
              ]
            },
            options: {
              scales: {
                yAxes: [
                  {
                    ticks: {
                      beginAtZero: true,
                      stepSize: 20
                    }
                  }
                ]
              }
            }
        });

    })
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ruth
Solution 2 Sergey Rudenko