How can I use piwik in an ember application? - ember.js

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.

Related

emberjs loading spinner with findRecord

EmberJS 3.4
I'm loading a Project entity from a backend which takes a couple of seconds. Now I would like to show a spinner during loading.
as described I created a project-loading.hbs (also tried with loading.hbs) https://guides.emberjs.com/release/routing/loading-and-error-substates/
project model class:
export default AuthenticatedRoute.extend({
model(params) {
return this.store.findRecord("project", params.projectname);
},
actions: {
refresh: function() {
this.refresh();
}
}
});
though it takes time to load the entity, the loading template seems not to be rendered/shown. Am I doing something wrong ?
For a route called project (routes/project.js), the loading template should be called project-loading.hbs.
I cloned your project and actually made it work (Ember CLI 3.4.3) by adding templates/project-loading.hbs, adding a sleep(30) call to your /api/projects/:name endpoint and going to a URL like http://localhost:4200/projects/hallo.
Do you have the problem when transitioning to the route internally (by using transitionTo or the {{link-to}} helper with a model for instance) or by entering the URL manually? Note that model hook is not executed when you transition to a route and pass in a model context (see https://guides.emberjs.com/v3.4.0/routing/specifying-a-routes-model/).
I ended up with adding the following code to the application adapter:
// not very ember way of doing this, but quite simple :)
$(document).ajaxStart(() => {
$('#spinner').removeClass('hide');
});
$(document).ajaxStop(() => {
$('#spinner').addClass('hide');
});
I really would prefer doing it the ember way. for now, this seems to do the trick.
for anyone interested, here's the complete project: https://github.com/puzzle/mailbox-watcher/tree/master/frontend

didInsertElement in Ember 2.0+

Ember.View is deprecated, in favor of Components. That's great but I'm having trouble making sense of the 2.0 release.
Most often, I used the didInsertElement hook to run some jQuery code etc. But now that the Em.View class has been deprecated, how can I achieve the same thing? I don't want to create a component or anything like that. It doesn't make sense to create components for normal pages(routes). Simply because its not a re-usable thing plus component's scopes are isolated.
Say we have a about route, and when the template is rendered I just want to sun some jQuery code. How can I do this in Ember 2.0+?
You could take advantage of didTransition hook and Ember.run.next. Check my solution:
export default Ember.Route.extend({
actions: {
didTransition() {
Ember.run.next(this, 'initParticles');
}
},
initParticles() {
let ammount = (window.matchMedia('(max-width: 456px)').matches) ? 40 : 100;
particlesJS('particles-js', {
// my options
});
}
});
While it doesn't seem like the best approach, creating a component is probably your best option. Soon we'll have routeable components which will take over much of what controllers and views use to do. Creating a component and just inserting it into your template should put you on a good path to be ready for routeable components.

How to use a library to fetch data in Ember

I am still very new to the world of Ember, and I'm still trying to understand EmberJS and Ember Data (latest version). In my previous (non-Ember) Node app, I included a library that handled all my REST calls to where my data was stored. It set up the connection to the server and handled all the error handling and parsing into a nice and tidy JSON object, and even handled multiple calls to the server in case the response was too big for one call. I can fetch individual records, but if I wanted to fetch a bunch of records, all I had to do was initialize the library object ('myObj') and call myObj.fetchAll(config) to initiate the fetch. Then I just have to wait on several events.
Example
myObj.on('record', function() { // Each record is an event }
myObj.on('error', function () { ...}
myObj.on('end', function () { // After the last record is retrieved }}
I would very much still like to use this library in Ember, but I have no idea how to go about setting it up. I haven't been able to find any examples of creating my own Adapter (is that the right terminology) that would allow me to do this.
Is this something I can do with Ember, or is it not recommended?
I would strongly suggest you use ember-data before attempting something non-standard as you're learning. Virtually all the documentation, and help will specifically be about ember-data. This is a good starting point: http://guides.emberjs.com/v1.13.0/models/
It's perfectly possible to use your own models and use a custom rest interface. You initiate your myObj.fetchAll(config) call on the router. If it's waiting for an event, return a promise and resolve it when the event returns. I don't know anything about your library but it would look something like:
export default Ember.Route.extend({
model() {
return Ember.RSVP.Promise(function(resolve){
var records = [];
myObj.on("record", (record) => {
records.pushObject(record);
});
myObj.on("end", () => {
resolve(records);
});
myObj.fetchAll(ENV.config);
});
}
});
In imperfect contrast, this is how you glue things together from your adapter to your template normally in ember:
Configuring a REST endpoint:
export default DS.RESTAdapter.extend({
host: 'https://api.example.com'
});
Defining a model:
export default Model.extend({
name: attr('string')
});
Fetching data in your route:
export default Ember.Route.extend({
model() {
return this.store.findAll('person');
}
});
Rendering the data:
{{#each model as |person|}}
{{person.name}}
{{/each}}
It's all pretty straight forward if you stick to the default way of doing things.

Loading bar that tracks completed HTTP requests for Ember.js

I've been looking around, and short of writing a basic one myself, I couldn't find a library that already exists for Ember that displays a small loading line at the top of the page that completes when all the http requests have completed for a page transition (whether that be images loading, JSON being fetched etc).
There's this for Angular: http://chieffancypants.github.io/angular-loading-bar/, but wondering if Ember has any options already.
Cheers.
EDIT: I've found this article as well about a jQuery plugin, which I imagine could be adapted: http://tutorialzine.com/2013/09/quick-tip-progress-bar/. Still keen on hearing if anyone knows of anything already integrated into the Ember request lifecycle though.
You can use fantastic javascript component NProgress (http://ricostacruz.com/nprogress)
and then you can initialize it in Application.ready event using jQuery like this
window.App.ready = function () {
$(document).ajaxStart(function () {
NProgress.start();
});
$(document).ajaxStop(function () {
NProgress.done();
});
};

Is there a way to get a callback when Ember.js has finished loading everything?

I am building an Ember.js app and I need to do some additional setup after everything is rendered/loaded.
Is there a way to get such a callback? Thanks!
There are also several functions defined on Views that can be overloaded and which will be called automatically. These include willInsertElement(), didInsertElement(), afterRender(), etc.
In particular I find didInsertElement() a useful time to run code that in a regular object-oriented system would be run in the constructor.
You can use the ready property of Ember.Application.
example from http://awardwinningfjords.com/2011/12/27/emberjs-collections.html:
// Setup a global namespace for our code.
Twitter = Em.Application.create({
// When everything is loaded.
ready: function() {
// Start polling Twitter
setInterval(function() {
Twitter.searchResults.refresh();
}, 2000);
// The default search is empty, let's find some cats.
Twitter.searchResults.set("query", "cats");
// Call the superclass's `ready` method.
this._super();
}
});
LazyBoy's answer is what you want to do, but it will work differently than you think. The phrasing of your question highlights an interesting point about Ember.
In your question you specified that you wanted a callback after the views were rendered. However, for good 'Ember' style, you should use the 'ready' callback which fires after the application is initialized, but before the views are rendered.
The important conceptual point is that after the callback updates the data-model you should then let Ember update the views.
Letting ember update the view is mostly straightforward. There are some edge cases where it's necessary to use 'didFoo' callbacks to avoid state-transition flickers in the view. (E.g., avoid showing "no items found" for 0.2 seconds.)
If that doesn't work for you, you might also investigate the 'onLoad' callback.
You can use jQuery ajax callbacks for this:
$(document).ajaxStart(function(){ console.log("ajax started")})
$(document).ajaxStop(function(){ console.log("ajax stopped")})
This will work for all ajax requests.
I simply put this into the Application Route
actions: {
loading: function(transition, route) {
this.controllerFor('application').set('isLoading', true);
this.router.on('didTransition', this, function(){
this.controllerFor('application').set('isLoading', false);
});
}
}
And then anywhere in my template I can enable and disable loading stuff using {{#if isLoading}} or I can add special jQuery events inside the actual loading action.
Very simple but effective.