Using FastBoot and localStorage

The FastBoot docs say that you can’t use localStorage with fastboot…but I’m finding otherwise. But before I continue down this path I want to be sure this is a tenable solution. Newb to both fastboot and localStorage.

I’m writing a shopping cart app that saves the cart contents to localStorage. The cart is initialized via an instance-initializer:

export function initialize(appInstance) {
    let CartService = appInstance.factoryFor('service:cart');
	let cart = CartService.create();

	// check if there's a cart in localstorage
	if (window.localStorage && window.localStorage.getItem('cart')) {
		cart.loadCart(window.localStorage.getItem('cart')) // existing cart
	} else {
		cart.createCart(); // create new cart
	}
	
    appInstance.register('cart:main', cart, { instantiate: false });
    appInstance.inject('controller', 'cart', 'cart:main');
    appInstance.inject('component', 'cart', 'cart:main');
}
export default {
    name: 'cart',
    initialize
};

OK when that runs in fastboot obviously the window.localStorage stuff evaluates to false and the cart.createCart() method is called in the cart service. I’m getting around the inevitable error by just checking if I’m in the fastboot environment. If so, don’t do anything.

// cart.js service
...
fastboot: Ember.inject.service(),
isFastBoot: Ember.computed.reads('fastboot.isFastBoot'),

createCart() {
	if (!get(this, 'isFastBoot')) { // skip if in fastboot
        let cart = this.get('store').createRecord('cart');
	    cart.save().then(response => {
			window.localStorage.setItem('cart', response.get('id')); 
		});
        set(this, 'cartObj', cart);
	}
}
...

So when the instance initializer runs in the browser, localStorage is available and everything works as normal. When I hard refresh or reboot stuff, everything has persisted as it should.

Is there any problem with this approach?

If not, is there a way to determine the environment (fastboot or not) in the instance-initializer itself?

Well, to answer my 2nd question, looks like just checking for localStorage in the instance-initializer works as a test that you’re in the FastBoot environment:

export function initialize(appInstance) {
    let CartService = appInstance.factoryFor('service:cart');
	let cart = CartService.create();

	// check if there's a cart id present in localStorage
	if (window.localStorage) {
		if (window.localStorage.getItem('cart')) {
			cart.loadCart(window.localStorage.getItem('cart'))
		} else {
			cart.createCart();
		}
	}

    appInstance.register('cart:main', cart, { instantiate: false });
    appInstance.inject('controller', 'cart', 'cart:main');
    appInstance.inject('component', 'cart', 'cart:main');
}

export default {
    name: 'cart',
    initialize
};

Rather you should hook into the fastboot service.

fastboot: Ember.inject.service()

Then you can do the following:

if (this.get("fastboot.isFastBoot")) {
  // Code goes here
}
1 Like