简体   繁体   中英

How to use saved data in Ionic/Angular?

I am building an Ionic application, and am having trouble using the data I have saved with this.storage.set . When I set a variable to the output (var) and console.log it within the this.storage.get function, I can see that it is set to the value of my saved data, but as soon as I try to use the variable elsewhere (like in my graph) nothing appears. When trying console.log again it appears as undefined.

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

How do I get this saved data into a variable?

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
              }
            }
          ]
        }
      }
    });
  }
}

use localStorage instead of Ionic Storage .

  • Set Data localStorage.setItem('key', value)
  • Get Data localStorage.getItem('key')

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
              }
            }
          ]
        }
      }
    });
  });
}

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
                    }
                  }
                ]
              }
            }
        });

    })
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM