How to detect browser in Ember - ember.js

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'}

Related

How to implement vuex-persistedstate in vue/ssr

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
})
}

Ember - using api/server data

I am new to ember and I like what I see so far. I have done the tutorial and found to to be pretty easy to get something up and running. My question has to do with using mirage vs real data. I used mirage to stub in some data but now I would like to link to to real data. I would think this should not be too hard since I have the models..etc set up I just need to call an api instead of mirage. I have not seen a clean example of how best to do this.
Thanks
You can turn mirage on/off for all requests per environment in config/environment.js e.g. off for development, on for testing,
// config/environment.js
if (environment === 'development') {
ENV['ember-cli-mirage'] = {
enabled: false
};
}
if (environment === 'test') {
ENV['ember-cli-mirage'] = {
enabled: true
};
}
Or if you leave mirage on for everything, allow specific endpoints to with passthrough:
http://www.ember-cli-mirage.com/docs/v0.3.x/configuration/#passthrough

ember dynamic adapter host update

I have an adapter something like this:
var Adapter = DS.RESTAdapter.extend({
host: 'http://localhost:4200'
});
if (config.environment === 'production') {
Adapter.reopen({
host: 'http://foo.example.com'
});
}
This has been working for a while, but recently something breaks. My ember app interfaces with a number of different subdomains (eg foo.example.com and bar.example.com). My understanding is that reopen changes all instances, which is what I think happens. When I browse to '/bar' it uses the correct adapter in production, but browsing to '/foo' still uses the bar.example.com endpoint.
My question is two fold. Firstly, am I using the right approach here?
Secondly, I'd like to change the adapter based on a runtime setting. I need to work around IE8 lack of CORS support so am thinking that if I have an ie8 switch, the adapter should hit example.com/foo instead of foo.example.com. In my mind these two areas are conceptually related, but I'm happy to be wrong.
update
To simplify things, I essentially want to find the hostname of the request and pass that into the adapter. For example if I browse to www.example.com I want the adapter to go fetch a record from www.example.com/foo, or when browsing to www.example2.com I want the adapter to fetch the record from www.example2.com/foo. I hope that makes sense. Is this even possible?
I'm not 100% sure on this, but my guess is that the value is being cached. My recommendation is to make host a volatile computed property. This actually works out better for you, since that will allow you to better select the host based on runtime configuration. Try something like this:
var Adapter = DS.RESTAdapter.extend({
host: function() {
if (config.environment === 'production') {
return 'http://foo.example.com';
} else {
return 'http://localhost:4200';
}
}.property().volatile()
});
Because Ember-Data always uses Ember's get method to fetch properties, changing host from a normal property to a computed one should make no difference. And because of that, you're able to select the host at runtime, and make sure that it's computed every time. (Don't worry about the performance of not caching that value, I promise it won't make a noticeable difference.)
import ENV from 'ember-arp-roomviewer/config/environment';
export default DS.JSONAPIAdapter.extend({
namespace: 'arp/v1',
//host: 'http://localhost/arp/index.php/wp-json',
//host: 'http://www.acme.net/myroomplan/wp-json',
host: function() {
if (ENV.environment === 'production') {
return 'http://www.acme.net/myroomplan/wp-json';
} else {
return 'http://localhost/arp/index.php/wp-json';
}
}.property().volatile(),
headers: {
'Content-type': 'text/plain' // Stops OPTION headers being sent PITA
}

ember-cli App.get / App.set throw undefined

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')

How can I use piwik in an ember application?

Is there any component or plugin that I can use, to integrate piwik into an ember application?
It's very simple actually. Sadly I haven't found out yet how I can track the individual views. But this will get you going with a basic set-up that also scales well.
Put this in your ApplicationRoute it hooks the route's didTransition so that every time you transition between routes data gets send to the Piwik server.
actions: {
didTransition: function () {
Ember.run.once(this, function () {
window._paq = _paq || [];
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
_paq.push(['setTrackerUrl', 'https://[Piwik server]/piwik.php']);
_paq.push(['setSiteId', 1]);
});
}
}
And don't forget to put a reference to Piwik.js in your application template to load the Piwik tracking library.
<script src="https://[Piwik server]/piwik.js" async defer></script>
There doesn't seem to be an all-integrated solution for Ember like there is for AngularJS.
You can have a look at this forum thread which may get you started.
You may also want to have a look at how it's working in AngularJS: http://luisfarzati.github.io/angulartics/ or https://github.com/mike-spainhower/angular-piwik
You can use ember-cli-piwik. It's quite simple:
Install the addon:
ember install ember-cli-piwik
Then configure it in your config/environment.js
piwik: {
sid: 123,
url: 'https://your-piwik.endpoint.com'
}
For more information, read the docs.