Ionic Vue Capacitor Preferences

I am trying to get local storage to work on Ionic Vue using Capacitor Preferences

I have run this:

npm install @capacitor/preferences

I have imported in one of my SPA’s, as follows:

import { Preferences } from '@capacitor/preferences';

then in a method that I call, I am running this to store a value:

      const key = 'abc';
      const value = 'my-value';
      Preferences.set(key, value) 

then in another method, I run this to retrieve the value from the key

      const key = 'abc';
      Preferences.get({ key }).then(result => {
        const value = result.value;
        // do something with the value
        console.log("retreived data", result, value)
      });

But the value always returns as undefined.

I have tried quite a few options to get it to work including trying to create a storage, which doesn’t work, as I it looks like this is an old method.

The help doc doesn’t help me to clarify why the above doesn’t work: Preferences Capacitor Plugin API | Capacitor Documentation

Can anyone help please?

FYI, I am running Vue 3 and finding lots of explanations for how to get this to work for other frameworks and older versions of storage, but not for Vue.

Hi, I think the issue might be the usage for the Preferences.set() is not correct.

const key = 'abc';
const value = 'my-value';

// Preferences.set(key, value)
Preferences.set({ key, value });

The help doc doesn’t help me to clarify why the above doesn’t work: Preferences Capacitor Plugin API | Capacitor Documentation

Well, this actually quite true, I’m also feeling this way sometimes.

The example section is at the very top of the page, and the description of the each method is at the bottom. So I need to scroll back and forth in order to understand the api. And sometimes I just totally forget to scroll to the top check the example section :rofl:


One extra thing you could try to avoid this kind of bug in the future, is adding typescript in your vue 3 project, the benefit is that typescript could help us to catch the bug like this:

Hope these information is helpful :smile:

2 Likes

Thank you. It was too obvious!

I guess I’ll put that down to coding fatigue. I copied and pasted the code from somewhere, where it was obviously incorrect.

This front-end developing is somewhat of a confusing affair, what with capacitor vs cordova, storage vs preferences, different frameworks that you have to learn to detect to make sure you are looking at the one you are using, and then (sometimes) slightly different syntax from one version of Ionic to another + the same for different versions of Vue + people then write their own components and it’s hard to know which one to use… etc etc.

As for typescript, I can see that it might help in this case, but I find it annoying to code with. Maybe I will have to change my ways… not today though.

@jonz94 on a separate note, have you got json.stringify to work?

I can’t store a json converted to a string. It always comes back as undefined.

This is how I am doing it. This is part of a wrapper I wrote around native storage.

public async get(key: string): Promise<any> {
    const { value } = await Preferences.get({ key: key })

    if (value == null) {
        return
    }

    return JSON.parse(value)
}

public set(key: string, value: unknown): Promise<void> {
    return Preferences.set({
        key: key,
        value: JSON.stringify(value),
    })
}

Thank you @twestrick

That looks like TypeScript to me. My mobile app is written in JavaScript.
I am wondering if I have to give up and move to TypeScript :slight_smile:

Interestingly it looks similar to my code, but not exactly the same:

    storeJson2 (key, value){
      const jsonString = JSON.stringify(value)
      Preferences.set({key, jsonString}) 
    },

    getJson2 (key){
      Preferences.get({ key }).then(result => {
        console.log("Summary of request for output: ", key, result)
        if (result.value != 'undefined'){
          let json = JSON.parse(result.value)
          console.log("Summary of actual output: ", key, result, result.value, json)
        }
      });
    },

I never get to the 2nd console log in the getJson2 function, as the output (result.value) is always equal to value:'undefined"

image

I wonder what I am going wrong?

If I pass a simple string to the storeJson2 function, it works.

When I convert an object to a string, it wraps it in curly brackets “{” and “}” and this seems to be the cause of it not working.

I wonder if the issue is because I am not using async on my retrieve…

Your code looks ok to me. I would use async/await over then() - comparison.

Are you calling getJson2() right after storeJson2()? Preferences.set() is async so it might be that the value isn’t set yet when you are calling getJson2().

For my wrapper if I wanted to wait until the value was set, I would do the following:

await MyStorageWrapper.set('my_key', myValue)
1 Like

I modified my getJson2 code to be similar to your and moved it to mounted from methods…

    // Async function
    async function getData(key) {
        const { value } = await Preferences.get({ key})
        if (value == null) {
            return
        }
        return JSON.parse(value)
    }

    // Call the async function
    getData(this.scheduleName);


I still get an error related to “undefined” being returned vs the string that I attempted to store with the storeJson2 function

image

Also, I tested further and when I pass the key and value through my functions, I have issues with the code, but when I declare const within the functions (hardcoding for testing purposes, it works)… time to stop and look at this again with a fresh pair of eyes tomorrow.

EDIT: Just read your post from above. I will look at the link and try out your suggestion tomorrow. Thank you!

And yes, I am calling get straight after store… for testing purposes. Maybe that’s the issue!