# Is it possible to cache information for use between Perspective client sessions

**URL:** <https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493>\
**Category:** Ignition\
**Tags:** ignition80, perspective\
**Created:** [June 10, 2020, 1:09pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493 "2020-06-10T13:09:26Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [June 10, 2020, 1:09pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/1 "2020-06-10T13:09:26Z")

</div>

I haven't looked into this at all, but thought I'd ask. I want to be able to cache certain things in the client's device such as login information and other configuration they might customise so I can reload it the next time they open the client. This would be mostly relevant to mobile devices.  
Is this possible? And if so, how would I do it? And if not, is it technically possible as a feature request?

Even if I write this data into a database table stored on the gateway. Can I get the details about the client such as a unique identifier that would remain constant across sessions? (clearly I have no Web dev experience, as I'm guessing the answer is pretty obvious)

EDIT: looks like I posted about this twice..

> [@Perspective: How to cache information between client sessions](http://forum.inductiveautomation.com/t/perspective-how-to-cache-information-between-client-sessions/26939):
>
> EDIT: It isn’t currently possible in 8.0.3, as confirmed by support, however I’ve added an idea suggestion if anyone wants to upvote it. I’ve asked this question before for the old Mobile Module: [Ignition Mobile Fixed Client Identifier](http://forum.inductiveautomation.com/t/ignition-mobile-fixed-client-identifier/16682) I’m looking to do the same thing in Perspective. Is there a way to store cookies (or otherwise) on an end-user device so that I can re-use that data when they launch the client again? I want to be able to cache user-logins so that users don’t need to log in al…

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 10, 2020, 1:12pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/2 "2020-06-10T13:12:27Z")

</div>

It should be possible to use a browser’s local storage, with permission from the user. You could probably do this today with the SDK.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 10, 2020, 4:42pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/3 "2020-06-10T16:42:45Z")

</div>

Doing this in a first party way is something we’d like to do, but there’s no timeline or exact feature specification for that yet.  
For now, you’d have to either use a custom module or a database, as mentioned.  
`session.props.device.identifier` is a somewhat stable identifier. It’s not guaranteed to be stable, because the browser/mobile device/user could reset their cache/uninstall+reinstall the app, etc and get a new identifier, but it should be reasonably stable.

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [June 10, 2020, 4:53pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/4 "2020-06-10T16:53:41Z")

</div>

> [@paul-griffith](#):
>
> or a database

I currently do this for app config Settings, I keep a session custom prop that contains all the users preferences in an object, bind it to a named query, and then on changes update that json in the database. Works well for most things but credentials are the only place this would fail.

I look forward to seeing that kind of stuff built in, in the meanwhile I typically just require authentication on the project anyway so they don’t have to remember to login and are forced to. Not a perfect solution but it works

Notably this is the main way I handle maintaining a users preferred theme

---

<div class="post-metadata">

**Author:** ![ryanjmclaughlin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryanjmclaughlin/32/4318_2.png) [@ryanjmclaughlin](https://forum.inductiveautomation.com/u/ryanjmclaughlin)\
**Post date:** [September 1, 2020, 8:38pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/5 "2020-09-01T20:38:35Z")

</div>

> [@kgamble](#):
>
> I keep a session custom prop that contains all the users preferences in an object, bind it to a named query, and then on changes update that json in the database.

I'm trying to do the same thing, but keep struggling on the update to the DB. How are you passing the object into the NamedQuery to insert into the DB? I was hoping to just send the JSON of the object, but the change script only seems to give me the qualified object.

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [September 1, 2020, 9:54pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/6 "2020-09-01T21:54:16Z")

</div>

> [@ryanjmclaughlin](#):
>
> I was hoping to just send the JSON of the object, but the change script only seems to give me the qualified object.

I dont still have access to that project, however you should be able to take the `currentValue.value` and use `system.util.jsonEncode()`to turn it into a string that will fit in the database

Then bind it to a named query weith the users username as a parameter so when they login it pulls the version from the database

---

<div class="post-metadata">

**Author:** ![ryanjmclaughlin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryanjmclaughlin/32/4318_2.png) [@ryanjmclaughlin](https://forum.inductiveautomation.com/u/ryanjmclaughlin)\
**Post date:** [September 2, 2020, 6:11pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/7 "2020-09-02T18:11:59Z")

</div>

Tried that, but its gets weird…

This is the result in the DB

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/2/0/200c0b3e1a3fa518ea7248095be4c2b61ce3f81f.png)

After running

```auto
	data = {'username':self.props.auth.user.userName, 'prefs': currentValue.value }
	system.db.runNamedQuery('ignition/updateUserPrefs', data)

```

on the change of session.custom.userPrefs

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/7/8788e1fd1f714ba56a0ff60383f61ca237c48cbc.png)

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [September 2, 2020, 10:15pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/8 "2020-09-02T22:15:34Z")

</div>

Put a `system.util.jsonEncode(currentValue.value)`

In the place of the current reference to `currentValue.value`, that should convert it into a string with none of the qualifying properties

To clarify: a JSON string, that when you bind it out afterwards you will want to use jsonDecode to turn back into a dictionary

---

<div class="post-metadata">

**Author:** ![ryanjmclaughlin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryanjmclaughlin/32/4318_2.png) [@ryanjmclaughlin](https://forum.inductiveautomation.com/u/ryanjmclaughlin)\
**Post date:** [October 9, 2020, 2:04pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/9 "2020-10-09T14:04:02Z")

</div>

> [@kgamble](#):
>
> Put a `system.util.jsonEncode(currentValue.value)`

Still cant seem to get this working. If I do the above, the value in the DB becomes NULL.

I found another way, to do this by just using self.custom.userPrefs as the self object is the session object in this scope, BUT, it is a odd object and logs to the DB in the following format

```auto
<ObjectWrapper>: {u'subObject': <ObjectWrapper>: {u'key': u'value'}, u'theme': u'dark2', u'hello': u'workld'}

```

I tried looking at the java docs but I cant seem to find a way to just get this as basic JSON to log to the DB. It is coming across as an ObjectWrapper only.

This seems to work ok, but it only works for a single level object and seems like a hack, I seem to be missing something super simple here, don't know why storing this as JSON is so hard....

```auto
keys = self.custom.userPrefs.keys()
	
	prefs = {}
	for key in keys:
		prefs[key] = self.custom.userPrefs[key]
	
	data = {'username':self.props.auth.user.userName, 'prefs': system.util.jsonEncode(prefs) }
	system.db.runNamedQuery('ignition/updateUserPrefs', data)

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [October 9, 2020, 3:10pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/10 "2020-10-09T15:10:00Z")

</div>

```auto
from com.inductiveautomation.ignition.common import TypeUtilities
jsonStr = str(TypeUtilities.pyToGson(currentValue.value))

```

Try this?

---

<div class="post-metadata">

**Author:** ![ryanjmclaughlin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryanjmclaughlin/32/4318_2.png) [@ryanjmclaughlin](https://forum.inductiveautomation.com/u/ryanjmclaughlin)\
**Post date:** [October 13, 2020, 4:22pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/11 "2020-10-13T16:22:12Z")

</div>

> [@paul-griffith](#):
>
> from com.inductiveautomation.ignition.common import TypeUtilities jsonStr = str(TypeUtilities.pyToGson(currentValue.value))

Close, but still has qualified values for all the submembers....

```auto
{"theme":{"value":"light","quality":{"code":0},"timestamp":"Oct 13, 2020, 12:20:31 PM"}}

```

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/2/3/23070c98d31f481ce1649b43bdd4f6e3a0685c38.png)

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [October 13, 2020, 5:05pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/12 "2020-10-13T17:05:41Z")

</div>

What version are you using, specifically? This area was actively in flux between 8.0.15 -\> .16, though I think everything’s supposed to be resolved in 8.0.17/8.1.0 RC3/final.

---

<div class="post-metadata">

**Author:** ![ryanjmclaughlin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryanjmclaughlin/32/4318_2.png) [@ryanjmclaughlin](https://forum.inductiveautomation.com/u/ryanjmclaughlin)\
**Post date:** [October 13, 2020, 5:28pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/13 "2020-10-13T17:28:22Z")

</div>

ahhhh .16 right now Will hold out for .17 to try again.

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [December 14, 2020, 9:41pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/14 "2020-12-14T21:41:37Z")

</div>

> [@paul-griffith](#):
>
> from com.inductiveautomation.ignition.common import TypeUtilities jsonStr = str(TypeUtilities.pyToGson(currentValue.value))

This still seems to be an issue in 8.0.17, the output json including dictionary keys for each aspect of a qualified value.

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [December 14, 2020, 10:29pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/15 "2020-12-14T22:29:51Z")

</div>

In the meanwhile this should work for you:

```auto
def make_values(obj):
    if hasattr(obj,'iteritems'):
        # dictionary
        ret = {}
        for k,v in obj.iteritems():
            ret[k] = make_values(v.value)
        return ret
    elif hasattr(obj,' __iter__'):
        # list (or the like)
        ret = []
        for item in obj:
            ret.append(make_values(item.value))
        return ret
    else:
        # anything else
        try:
            return obj.value
        except:
            return obj

preferences = make_values(currentValue.value)

```

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [March 24, 2022, 6:16pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/16 "2022-03-24T18:16:07Z")

</div>

> [@paul-griffith](#):
>
> Doing this in a first party way is something we’d like to do, but there’s no timeline or exact feature specification for that yet.

Is this a feature that ever made its way to the backlog? While using a database for this is surely possible, it would be great if there was a cleaner first-party implementation of this

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [March 28, 2022, 2:31pm UTC](https://forum.inductiveautomation.com/t/is-it-possible-to-cache-information-for-use-between-perspective-client-sessions/35493/17 "2022-03-28T14:31:02Z")

</div>

It’s still in the “thing we’d like to do” pile, but we don’t have an exact specification for implementation nor timeline for it.
