从 Ionic Storage 设置/获取对象和值

Posted

技术标签:

【中文标题】从 Ionic Storage 设置/获取对象和值【英文标题】:Setting/Getting Objects and values from Ionic Storage 【发布时间】:2022-01-17 00:07:44 【问题描述】:

我正在为大学做一个简单的天气应用程序项目,我非常头疼使用离子存储返回已传递到存储的值。 该应用程序相当基本,从 API 获取纬度/经度值,将它们保存在存储中,然后将它们传递给另一个 API 以获取更多信息并将其显示在主页上。

我可以从 API 中直接获取值,并且我已经从 API 中提取了我需要的相关信息,将它们存储在提供程序内的对象 cityInfo 中(下面,这可能是非常不正确的做法所以欢迎所有建议。

private cityInfo = 
    cca2: "",
    commonName: "",
    flag: "",
    lat:  0,
    lng: 0
  ;

然后我将存储中的值设置如下

packCityInfo(cityData: any): void 
    this.cityInfo.cca2 = (cityData[0].cca2);
    this.cityInfo.commonName = (cityData[0].name.common);
    this.cityInfo.flag = (cityData[0].flags.png);
    this.cityInfo.lat = (cityData[0].latlng[0]);
    this.cityInfo.lng = (cityData[0].latlng[1]);
this.storage.set('cityInfo', this.cityInfo);

如果我 console.log(cityInfo) 它会正确打印不同属性的不同值,即

cca2: "GB"
commonName: "United Kingdom"
flag: "https://flagcdn.com/w320/gb.png"
lat: 54
lng: -2

我遇到的问题是弄清楚如何从存储中访问这些值。我认为我遇到的问题与同步性有关。我发现第一次尝试保存设置时请求会失败并说“.lat 未定义”,但第二次保存设置时请求会成功,我将从存储的 API 请求中获取信息.

我的 saveSettings() 函数在我的 settings.ts 页面中如下

this.storage.set('city', this.cityName);
    this.storage.set('units', this.units);

    this.cityDataService.getCityDataFromAPI(this.cityName);

    this.storage.get("cityInfo").then((val) => 
      let cityInfo = val;
      // return val;
      this.weatherService.getWeatherFromApiCoordinates(cityInfo.lat, cityInfo.lng, this.units);
    ).catch((err) => 
      console.log(err);
    );

返回 “TypeError:无法读取 null 的属性(读取 'lat') 在 settings.ts:48"

服务非常标准,只处理 http 获取请求,所以我认为问题不在于它们吗? (可能是错误的)

getWeatherFromApiCoordinates(lat: number, lon: number, units: string) : void  
    let weatherData = this.http.get('https://api.weatherbit.io/v2.0/current?lat=' + lat + '&lon=' + lon + "&key=" + this.apiKey + '&units=' + units);
    weatherData.subscribe(data => 
      let currentWeather = data;

      this.packWeatherData(currentWeather);
    );
  

第二次运行 saveSettings() 函数时,它将正确显示值,但它会从先前设置的值中提取。 所以例如我运行

    都柏林, 都柏林, 法国。 它将返回 1.Err、2.Dublin、3.Dublin。

每次清除存储时都会运行 Error initial obv

我对承诺和同步性的概念不太了解,因此我们将不胜感激任何帮助。 (我大致了解这些概念,但实际上并不了解)

【问题讨论】:

我发现第一次尝试保存我的设置时,请求会失败并说“.lat 未定义” 那是在何时何地?请提供minimal reproducible example,谢谢! :) 嘿,抱歉,我添加了一些额外的上下文,当我稍后回到计算机时,我会尝试得到一个完全剥离的示例,谢谢您的建议 - x 【参考方案1】:

似乎是一个竞争条件,http-request 仍在执行,并且当您在其上调用 get 时未设置存储值。将数据设置到离子存储中是异步的。如果您需要等待某事发生,您可以随时致电async ... await on storage:

async doSomething() 
 await this.storage.set(...)
 await this.storage.get(...) // here is available!

虽然您也有使用 observables 的 http 请求。当然,您也可以将它们转换为 Promise,或者以其他方式将它们链接起来,以便在需要时正确获得所有数据。

实际上我什至没有看到您需要在这里等待存储,为什么不使用 switchMap 执行第二个请求,因为您需要前一个的响应执行下一个。这就是我会做的,所以只是一个建议......

服务:

getCityDataFromAPI() 
  return this.http.get(....)


getWeatherFromApiCoordinates(...)  
  return this.http.get(...);

然后组件会这样做:

this.weatherService.getCityDataFromAPI().pipe(
  switchMap(cityData => 
    return this.weatherService.getWeatherFromApiCoordinates(cityData[0].latlng[0], cityData[0].latlng[1], this.units)
  )
).subscribe(console.log)

如果您需要保存在存储中以备将来使用,您可以随时使用 tap 处理副作用。

【讨论】:

太好了,我现在来看看 switch 映射,它看起来可以解决很多这些问题! 通过将 observable 转换为 Promise 来解决我的特定问题。感谢您的建议!

以上是关于从 Ionic Storage 设置/获取对象和值的主要内容,如果未能解决你的问题,请参考以下文章

Ionic 5 使用 Ionic Storage 获取 JWT 并在 HTTP 调用中发送标头

ionic 2 local storage 获取并显示数据

应用程序开始时的 Ionic Secure Storage get()

Ionic2存储Promise.all范围

$.ajax 从 php 获取 json_encode($arr) 之后的对象,但是如何在 jQuery 中获取键和值?

如何从 Google Cloud Storage 中获取特定对象元数据信息?