简体   繁体   English

离子存储:TypeError:无法读取未定义的属性“获取”

[英]Ionic Storage : TypeError: Cannot read property 'get' of undefined

I'm using Ionic Storage to store data on the long run.从长远来看,我正在使用 Ionic Storage 来存储数据。 Right now i wanna retrieve data when i go to the Statistics page, so i called the Service i made and wrote the methods in the ngOnInit of the statistics page but it doesn't recognize the instanciation of the storage class if i understood the issue correctly but the weird thing is that it does work when i write the methods in the ionViewWillEnter().现在我想在我 go 到统计页面时检索数据,所以我调用了我创建的服务并在统计页面的 ngOnInit 中编写了方法,但是如果我正确理解了这个问题,它无法识别存储 class 的实例化但奇怪的是,当我在 ionViewWillEnter() 中编写方法时它确实有效。 I made both ngOnInit and ionViewWillEnter async but i still get an error for the ngOnInit.我使 ngOnInit 和 ionViewWillEnter 都异步,但我仍然收到 ngOnInit 错误。 I could go with the ionViewWillEnter trick if i'm not wrong it is similar to calling the methods in ngOnInit in my use case but i'm still curious of why it gets me errors...如果我没记错的话,我可以用 ionViewWillEnter 技巧 go 它类似于在我的用例中调用 ngOnInit 中的方法,但我仍然很好奇它为什么会出错......

TS of the statistics page:统计页面的TS:

import { StatsService } from './../service/stats.service';
import { Component, OnInit } from '@angular/core';

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

  testsAmount: any = 0;

  constructor(public statsService: StatsService) {}

  addJohn(){
    this.statsService.set("1", "john");
  }

  removeAll(){
    this.statsService.clearAll();
  }

  async getJohn(){
    console.log(await this.statsService.get("1"));
  }

  

  async ngOnInit() {
      await this.statsService.set("testSetngOnInit", "blabla");
      console.log("testSet initialized from the ngOnInit");
      console.log(await this.statsService.get("testSetngOnInit"));
  }

  async ionViewWillEnter(){
    await this.statsService.set("testSetionViewWillEnter", "blabla");
      console.log("testSet initialized from the ionViewWillEnter");
    console.log(await this.statsService.get("testSetionViewWillEnter"));
  }

  

}

TS of the Service:服务的TS:

import { Injectable } from '@angular/core';
import { Storage } from '@ionic/storage-angular';
import * as CordovaSQLiteDriver from 'localforage-cordovasqlitedriver';

@Injectable({
  providedIn: 'root'
})
export class StatsService {
  
  // private _storage: Storage | null = null;
  private _storage: Storage;

  constructor(public storage: Storage) { 
    this.init();
  }

  async init() {
    // If using, define drivers here: await this.storage.defineDriver(/*...*/);
    await this.storage.defineDriver(CordovaSQLiteDriver);
    const storage = await this.storage.create();
    this._storage = storage;
  }

  async keyExistence(key: string){
    if(await this.get(key) == null){
      return false;
    }
    else{
      return true;
    }
  }

  // Create and expose methods that users of this service can
  // call, for example:
  async set(key: string, value: any) {
    await this._storage?.set(key, value);
  }

  async clearAll() {
    await this._storage.clear();
  }

  async get(key: string) {
    return await this._storage.get(key);
  }

}

And this is what i get in the console:这就是我在控制台中得到的: 安慰

And my IndexDB:还有我的索引数据库:

索引数据库

Thanks in advance !提前致谢 !

The error message indicates that line 44 in stats.service.ts is the line which caused the issue.错误消息表明 stats.service.ts 中的第 44 行是导致问题的行。 Your component ngOnInit is indeed accessing the service instance, but the service itself is failing.您的组件ngOnInit确实在访问服务实例,但服务本身失败了。 I imagine this is because your constructor for StatsService is calling this.init();我想这是因为您的StatsService构造函数正在调用this.init(); , but the constructor is not awaiting it (and I don't think it can). ,但构造函数并没有等待它(我认为它不能)。 Thus when you try to access it that early (in ngOnInit) this._storage has not yet been initialized.因此,当您尝试在早期(在 ngOnInit 中)访问它时, this._storage尚未初始化。

The reason statsService.set appears to succeed is because that method calls this._storage?.set(key, value) - note the ? statsService.set似乎成功的原因是因为该方法调用this._storage?.set(key, value) - 注意? which is a null conditional, meaning if _storage is null then the whole expression evaluates as null .这是一个 null 条件,这意味着如果_storage是 null 则整个表达式的计算结果为null

I don't know for sure, but I assume ionViewWillEnter is called later in the component lifecycle, and the stats service constructor has had enough time to fully initialize.我不确定,但我假设ionViewWillEnter在组件生命周期的后期被调用,并且统计服务构造函数有足够的时间来完全初始化。 On the other hand, ngOnInit is called right after the component constructor.另一方面, ngOnInit在组件构造函数之后被调用。

Alright, I found the answer, This is actually very simple to solve.好吧,我找到了答案,这其实很容易解决。 so stupid that I didn't think about it.., So instead of instanciating the service in its own class, you have to instanciate it in the class where you use it: so in my case :太愚蠢了,我没想到..,因此,与其在自己的 class 中实例化服务,不如在使用它的 class 中实例化它:所以在我的情况下:

What I had in the service constructor:我在服务构造函数中的内容:

constructor(public storage: Storage) { 
    this.init();
  }

But the thing is the constructor cannot use the async statement so you can't tell your class to wait for it, so what you need is to init inside the ngOnInit of the class using it:但问题是构造函数不能使用异步语句,所以你不能告诉你的 class 等待它,所以你需要在 class 的 ngOnInit 中使用它来初始化:

My page using the service:我使用该服务的页面:

async ngOnInit() {
      await this.statsService.init();
  }

Hope this would help some people:)希望这会帮助一些人:)

Call init in your AppComponent to create an instance of storage.在 AppComponent 中调用 init 以创建存储实例。 and this should called only one time.这应该只调用一次。

export class AppComponent implements OnInit,{

  constructor(
    private storage: StorageService
    ) {}

  async ngOnInit() {
    await this.storage.init();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 TypeError:无法读取未定义的Ionic 3 / Angular 5的属性“ get” - TypeError: Cannot read property 'get' of undefined Ionic 3 /Angular 5 TypeError:无法读取离子中未定义的属性“firstName” - TypeError: Cannot read property 'firstName' of undefined in ionic IONIC 4:无法读取未定义的属性'get' - IONIC 4: Cannot read property 'get' of undefined 错误TypeError:无法读取未定义的属性'get' - ERROR TypeError: Cannot read property 'get' of undefined 离子本机http获取返回typeError-无法读取未定义的属性“ match” - ionic native http get return typeError - Cannot read property 'match' of undefined TypeError:无法读取未定义的属性'length'-Ionic和WordPress - TypeError: Cannot read property 'length' of undefined - Ionic and WordPress 错误TypeError:无法读取未定义的属性“名称”(离子4) - ERROR TypeError: Cannot read property 'name' of undefined (Ionic 4) 未捕获(承诺):类型错误:无法读取 ionic3 中未定义的属性“调用” - Uncaught (in promise): TypeError: Cannot read property 'call' of undefined in ionic3 离子性:未捕获(承诺):TypeError:无法读取未定义的属性“ length” - Ionic: Uncaught (in promise): TypeError: Cannot read property ‘length’ of undefined TypeError:无法读取未定义IONIC2的属性“就绪” - TypeError: Cannot read property 'ready' of undefined-IONIC2
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM