Preferences Trouble

Hi,
since updating my environment my project seems to be completey broken, and I dont know if I ever get my project working again. I used e.g. a simple storage class, but now I get errors.

Error: src/app/services/storage.service.ts:17:5 - error TS2322: Type 'GetResult' is not assignable to type '{ value: string; }'.
  Types of property 'value' are incompatible.
    Type 'string | null' is not assignable to type 'string'.
      Type 'null' is not assignable to type 'string'.

17     return (await Preferences.get({ key }));
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Error: src/app/services/storage.service.ts:26:23 - error TS2345: Argument of type 'string | null' is not assignable to parameter of type 'string'.
  Type 'null' is not assignable to type 'string'.

26     return JSON.parse(ret.value);
import { Injectable } from '@angular/core';
import { Preferences } from '@capacitor/preferences';

@Injectable({
  providedIn: 'root'
})
export class StorageService {

  constructor() { }

    async setString(key: string, value: string) {
        await Preferences.set({ key, value });
    }

    async getString(key: string): Promise<{ value: string }> {
        return (await Preferences.get({ key }));
    }

    async setObject(key: string, value: any) {
        await Preferences.set({ key, value: JSON.stringify(value) });
    }

    async getObject(key: string): Promise<{ value: any }> {
        const ret = await Preferences.get({ key });
        return JSON.parse(ret.value);
    }

    async removeItem(key: string) {
        await Preferences.remove({ key });
    }

    async clear() {
        await Preferences.clear();
    }
}

Why doesnt it work any more? How do I have to code it now?

I tried this in a new testapp:

  callMyMethods() {
    this.setString('msg', 'Hello Test-App');
    const value = this.getString('msg');
    console.log(`msg = ${value}`);
  }

  async setString(k: string, v: string) {
    await Preferences.set({ key: k, value: v});
  }

  async getString(k: string): Promise<string> {
    const ret = await Preferences.get({ key: k });
    return (ret.value || '');
  }

console.log shows

msg = [object Promise]

Why not “Hello Test-App”?

Hi,

The issue is that the type of the value return from this.getString('msg') is actually a Promise.

So, you need to use async/await or .then() in order to get the actual value inside the Promise.

Option 1. use async/await

  async callMyMethods() {
    this.setString('msg', 'Hello Test-App');
    const value = await this.getString('msg');
    console.log(`msg = ${value}`);
  }

Option 2. use .then()

  callMyMethods() {
    this.setString('msg', 'Hello Test-App');
    this.getString('msg').then((value) => {
      console.log(`msg = ${value}`);
    );
  }
1 Like

In my real app I actually use option 2, but what confused me is the GetResult.value: string hint, and thought I was getting a string back here directly.

getresult_string

I must admit that I have not yet fully understood this Promise issue.

Hey there, I know it’s an older subject but since it talks about preferences, I thought it would be a good place. I’m getting the preferences API (@capacitor/preferences) to work on the web. But when I use the iOS emulator, it’s not working. I don’t see the same result as in the web version.

I cannot figure why, and I can’t find any log about the problem in the emulator.

Is there anyone with the same problem?

Also is there anyway to debug the iOS emulator?

Thanks in advance

You can open DevTools in Safari to debug. Check out this article - Using Xcode iOS Simulator for Responsive Testing | BrowserStack

Thanks for the help! So the problem was that I was storing the data as a boolean, it works on the web but not on iOS. The value was cast and stored as a string on the web, but it was just not working on iOS.

2 Likes