I need to persist state in vue ssr app, but can't understand how to implement this.
As storage, I want to use cookies.
When I install the plugin as written in readme nothing happens, that it's strange: I expect an error because js-cookies calls "window".
The question is: how to implement vuex-persistedstate in vue/ssr?
I can access cookies in req.cookies, but I can't set cookies in the browser, and this expected because my store fill on server side, and js-cookies calls on server side.
Until the they fix this in source code, I managed this way:
storage.js
import CreatePersistedState from 'vuex-persistedstate'
let PersistedState
if (process.browser) {
PersistedState = CreatePersistedState(yourOptions)
}
export default PersistedState
store.js
import CreatePersistedState from 'src/util/plugins/storage'
...
const plugins = []
if (process.browser) {
plugins.push(CreatePersistedState)
}
export default function createStore() {
return new Vuex.Store({
state,
modules,
actions,
mutations,
getters,
strict: false,
plugins: plugins
})
}
Related
I have an ES6 class in Ember 3.1 which is being handed an ember data object called certifciate. I would like to be able to call .reload() on that certificate as follows:
#action
showCertificateInfo(this: DomainCard, certificate) {
this.setProperties({
isShowingCertificateModal: true,
selectedCert: certificate,
})
certificate
.reload()
.then(() => {
this.set('isShowingCertificateModal', true)
})
.catch(e => {
// TODO: handle this
})
}
However, if I do this, then Ember gives the following error/warning:
Assertion Failed: You attempted to access the 'reload' property
(of <DS.PRomiseObject:ember796>)... However in this case4 the object
in quetstion is a special kind of Ember object (a proxy). Therefore,
it is still necessary to use` .get(‘reload’)` in this case.
If I do as the code suggests and call .get('reload') instead, then I get an internal Ember error that this is not defined when calling this._internalModel. I get the same error when doing:
const reload = certificate.get('reload').bind(certificate)
reload().then()
...
What do I need to do to be able to reload this ember data object properly?
Actually, whe fundamental problem seems to be that the certificate model had an async relationship to the domain model, and by using {async: false}, we remove the need to get a proxyPromise object returned to us and remove the need to pull the content object out of the promise.
Pulling the content out of the proxy solved the problem:
const certContent = certificate.content || certificate
certContent.reload()
I'm still not sure why Ember 3.1 isn't able to work with the proxy properly, but this was the solution.
I have a function in angular 2 service which I would like to test.
service.ts
upload(){
let file = new Transfer();
file.upload(myfile).then( // my callback );
}
I would like to mock Transfer in my test using jasmine. I tried this in my
sevice.spec.ts
import { TransferMock as Transfer } from '../mocks/mocks' to mock it. But it is not working. This is how my test is instantiated .
describe('authentication service' , () => {
beforeEach(() => {
auth = new Service(<any>new HttpMock(), <any>new StorageMock())
});
it('initialize authentication',() => {
expect(auth).not.toEqual(null);
auth.upload('file'); //it fails here
});
})
edit
Transfer is not injected in the service. Only one function uses Transfer . So not injecting can reduce the initial loading time of the app i guess(would be happy to know other opinions) . So I would like to know if there is anyway to mock if its constructed this way ?
edit
Although I had accepted Martin's answer as it is the best practice, it has one issue which can happen when you use ionic-native plugins.If the plugin doesnt have browser support it can fail. In this case it happened when I inject it, with error FileTransfer is not defined . So I am back again, looking for suggestions.
In order to provide a mock for a class in a test, you need to inject the class in your implementation.
In your ngModule add Transfer to your providers. Then simply inject it into your service.
Then in your test you can use { provide: Transfer, useClass: TransferMock } in your TestBed providers.
Update
The primary purpose of Dependency Injection is to make code testable and to allow mocking - faking - stubbing of services.
Update
With Dependancy Injection you can configure a different set of providers for different environments.
For example, if you are running your application in the browser, and in a native mobile environment you can swap out your configuration.
In your module you could have something like this:
const TRANSFER_PROVIDER: any;
if (environment.browser) {
TRANSFER_PROVIDER = Transfer;
} else {
TRANSFER_PROVIDER = { provide: Transfer, useClass: NativeTransfer }
}
...
providers: [ TRANSFER_PROVIDER ]
NativeTransfer could be a simple stub that does nothing but prevent errors, or it could let the user know that this feature is not supported in their browser.
Does Ember have built-in way to detect browser? Something like this if using this library(bowser)
if (bowser.msie) {
...
} else if (bowser.gecko) {
...
} else if (bowser.webkit) {
...
}
Or, I can just npm install bowser, then import it and use it in Ember
I guess there won't be any builtin way in ember to detect browser AFAIK. Usually this kind of job will be delegated to ember addon, may be try ember-browser-checker if this is not fulfilled your requirement then you can consider any npm/bower libraries like you found bowser.
I implemented a little browsercheck as service be aware that this is not secure, but works for simple needs
Ember UserAgent is an Ember addon which exposes a userAgent service, making it easy to detect browser, device, OS and more.
It works in both browser & Fastboot environments and is as simple as:
const userAgent = this.get('userAgent');
userAgent.get('browser.isChrome'); // Boolean
userAgent.get('engine.isWebKit'); // Boolean
userAgent.get('os.info'); // => { name: 'Ubuntu', version: '11.10' }
userAgent.getDevice(); // => { model: 'iPhone 7', type: 'mobile', vendor: 'Apple'}
In Ember 2+, does anyone know how to get a reference to the Ember Store in order to troubleshoot Model mapping in the javascript console?
It was possible through App.__container__.lookup in Ember 1, but this doesn't exist anymore, and it's bloody hard to find documentation on this.
Thanks
If you look in your package.json, you should see a ember-export-application-global package that's installed by default (if not, install it). This will export your application not to the global App object, but to a global object that's named after your app. So you might have window.TodoList or window.ShoppingCart instead of window.App. From there you can use this line (similar to Ember 1.x.x):
AppName.__container__.lookup('service:store')
You can also do what I do and create an instance initializer for it:
export default {
name: 'store-on-app',
after: 'ember-data',
initialize(instance) {
const application = instance.container.lookup('application:main');
const store = instance.container.lookup('service:store');
application.set('store', store);
}
}
Then you can just use AppName.store.
If you don't want to install a separate package to access your app in the console, you can do it through window.Ember.Namespace.NAMESPACES. For example, something you can run in the console to find your app instance is:
var app = Ember.A(Ember.Namespace.NAMESPACES).filter(n => {return n.name === 'your-app-name'})[0];
From here, you can access the store on the app's container as explained by #GJK
var store = app.__container__.lookup('service:store');
I used this for debugging an Ember app in production which didn't have its container registered on the window. I found it out by looking through the ember-inspector source code, since it always has access to the container.
https://github.com/emberjs/ember-inspector/blob/2237dc1b4818e31a856f3348f35305b10f42f60a/ember_debug/vendor/startup-wrapper.js#L201
I'm converting a globals based real-time Ember app to an es6 based app that utilizes ember-cli. In my app I need to know the current route fairly often. In the globals version, I was doing this.
Globals Pattern
var MyApp = Ember.Application.create({
currentRoute : ''
});
MyApp.Route = Ember.Route.extend({
actions : {
didTransition : function () {
MyApp.set('currentRoute', this);
}
}
});
I could then do MyApp.get('currentRoute') from within my session or offline controllers when determining how / where to transition when certain events occurred.
When using ember-cli, I import the app to be able to reference it from the necessary controllers.
import MyApp from "../app";
But it turns out that MyApp.currentRoute, MyApp.get, and MyApp.set are all undefined.
Part of me thinks this is a bug in ember-cli that the application instance no longer has bound getters and setters. Part of me realizes it's not a great practice to store things on the application instance either.
I could get around this issue by converting all instances of MyApp.get and MyApp.set to Ember.get(MyApp, ...) and Ember.set(MyApp, ...) respectively, but I thought I'd ask here first as this seems to either be an issue with Ember-Cli or else something where there's a better recommended way to achieve what I need.
If you look at app.js (what you are importing), it is not your application instance, it is exporting a subclass of Ember.Application. That's why get et al are not available on it.
var App = Ember.Application.extend({ <----- NOT create
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
Resolver: Resolver
});
export default App;
To get the actual application instance from within your route use:
Ember.getOwner(this).lookup('application:main')