mainmatter / ember-cookies

Cookies abstraction for Ember.js that works both in the browser as well as with Fastboot on the server

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Working with objects, serialization & defaults

willviles opened this issue · comments

In my production app RiskMap, we store a lot of cookie information. We like to store certain values in objects for the sake of tidiness, and because it's logical that all data stored in the same object should expire at the same time.

Currently, updating cookie objects is a multi-step process, parsing and stringifying back-and-forth:

let myCookie = this.get('cookies').read('my-cookie');
myCookie = Ember.Object(JSON.parse(myCookie));
myCookie.set('foo-bar', true);
myCookie = JSON.stringify(myCookie);
this.get('cookies').write('my-cookie', myCookie, { maxAge: defaultCookieMaxAge });

This is a pattern we use a lot at RiskMap, so I've extended Ember Cookies to make working with objects easier and more DRY. TL;DR, the above example becomes:

this.get('cookies').writeObjProperty('myCookie', 'fooBar', true);

@marcoow @Turbo87, I'd be interested to know whether you'd be interested in merging some of the following features into Ember Cookies:

Configuration

Serialization

A global way of serializing cookie name and property keys so camel cased attributes can be used in js, but cookie JSON stored in a consistent manner.

// config/environment.js
ENV['ember-cookies'] = {
  serializer: 'dasherize'
}

Default max age/expires

Our user session is set to expire after 30 days. We want most of our other cookies to expire after that, too. The default value can be expressed either as defaultMaxAge or defaultExpires.

// config/environment.js
ENV['ember-cookies'] = {
  defaultMaxAge: 60 * 60 * 24 * 30,
  defaultExpires: 60 * 60 * 24 * 30
}

Object methods

readObj

readObj reads the cookie, automatically parses the object to JSON and asserts whether it is a valid object.

this.get('cookies').readObj('myCookie');
// returns Ember.Object instance || null

readObjProperty

readObjProperty returns the property value from the cookie object.

this.get('cookies').readObjProperty('myCookie', 'fooBar');
// => returns parsed value

Because all cookie objects are parsed into Ember Object instances, we can get deep property values using dot notation:

this.get('cookies').readObjProperty('myCookie', 'fooBaz.isGettable');

writeObj

writeObj asserts whether a POJO or Ember Object instance is passed and stringifies it as JSON before writing:

this.get('cookies').writeObj('myCookie', { fooBar: true }/*, options*/);
// "my-cookie" === { "foo-bar": true }

writeObjProperty

writeObjProperty enables updating an individual property inside a cookie object:

this.get('cookies').writeObjProperty('myCookie', 'fooBar', false/*, options*/);
// "my-cookie" === { "foo-bar": false }

clearObj

clearObj is just an alias for clear, for the sake of consistency.

this.get('cookies').clearObj('myCookie'/*, options*/);
// my-cookie === null

clearObjProperty

clearObjProperty simply sets a property to null, before stringifying and writing.

this.get('cookies').clearObjProperty('myCookie', 'fooBar'/*, options*/);
// "my-cookie" === { }

Thanks for the great writeup!

I honestly don't believe this is something that belongs in ember-cookies though. The idea behind ember-cookies is really to provide a low level cookies API that works both in the browser as well as in Node. Introducing functionality that allows using cookies as an object store that also has to deal with serialization etc. introduces a lot of additional complexity that just isn't necessary for the majority of use cases. Also using cookies in this way isn't actually advisable I'd argue (there might be edge cases in which doing this is actually fine and your app might be one of these edge cases) and I don't think we should advocate this kind of usage by providing dedicated APIs for it.

@marcoow I totally understand that and in fact I thought that would be the case!

I'd be interested to hear more as to why you say storing objects in cookies isn't advisable and whether you think it'd be worth me authoring an accompanying plugin - something like Ember Cookies Object Store?

I'd be interested to hear more as to why you say storing objects in cookies isn't advisable

You might run into problems with max cookie size, having to migrate data in cookies etc. In general you want to store only enough information in a cookie to be able to restore your full state from that. For more advanced things it's probably better to use localStorage or sessionStorage or even things like IndexedDB or so.

and whether you think it'd be worth me authoring an accompanying plugin - something like Ember Cookies Object Store?

I think everything's worth exploring ;)