How to add Ember to the onDeviceReady event in Phonegap? - javascript

In Phonegap we wait for the onDeviceReady event for our code to start executing. Following this path I added my Ember app like this:
var App = null; // Ember
var phonegap = {
initialize: function () {
this.bindEvents();
},
bindEvents: function () {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
onDeviceReady: function () {
App = Ember.Application.create({});
// Now I can start adding my Ember stuff, but
// even for a tutorial app that is somewhere between
// 100 to 200 lines and it will be harder to maintain
// inside here. So I wrap that with a function
// and put it outside.
addMyEmberStuff();
}
}
function addMyEmberStuff() {
// Ember Routes, Controllers, Views etc.
App.Router.map(function() {
});
App.IndexController = Ember.Controller.extend({
init: function () {
this._super();
// device API calls
// create/render View(?)
// trigger DOM events etc
}
});
}
I know that I can initialize an Ember app outside of the onDeviceReady and everything will keep working. The problem is that the index page of the app has calls to the device API and also some DOM events must occur before Ember starts working its magic.
This seems to me the proper way of doing things.
How do I solve this design for the case of a larger app where I want to have each Ember Controller/View/Template in its own file? I can't keep wrapping everything with the addMyEmberStuff function.

You want prevent you Ember application from starting before PhoneGap is ready. To do this you can use defer and advance readiness.
App = Ember.Application.create()
App.Post = ...
App.PostsRoute = ...
App.PostsController = ...
App.deferReadiness();
document.addEventListener('deviceready', function() {
App.advanceReadiness();
});
Once advanceReadiness is called Ember will begin routing for your application.

Related

Apache cordova : Alert and jquery ajax call is not working

I am working on small app that fetches database information in JSON format from PHP files. I am trying to write alert and jquery ajax call but both are not working/executing in app. But when I simultaneously check in browser then it is showing. I am new to Apache cordova platform. Can somebody please reply me on my issue? How can I resolve these basic issues in apps.
Platform : ios app. - running on --emulator
waiting for your response.
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
},
// Update DOM on a Received Event
receivedEvent: function(id) {
$("#defaultsetlocation").html("hello added new text");
alert("i am alert");
try
{
navigator.notification.alert('Hello', ok, 'Title', 'Button!');
}
catch(e)
{
alert("doesn't support!!");
}
console.log('Received Event: ' + id);
}
};
app.initialize();

Ember: Testing WillDestroyElement Logic of Component in an Integration Test

I have an Ember component...
Ember.Component.extend({
onDidInsertElement: function(){
var that = this;
Ember.run.scheduleOnce('afterRender', () => {
// Some code that sets up a jQuery plugin which attaches events etc
});
},
onWillDestroyElement: function(){
// Code that destroys the jQuery plugin (removing attached events etc)
}
}
Here's my integration test:
test('it renders', function (assert) {
this.render(hbs`{{my-component }}`);
// Here some code to make sure the rendered state is ok
// then...
// ?? How to fire the "willDestroyElement" lifecycle hook?
}
Assuming I know how to check for the existence of the jQuery plugin events on the page (e.g. using the technique described here), how do I actually test the teardown logic in my integration test?
You can use component.destroyElement (which mentions it will invoke willDestroyElement hook) or component.destroy.
Approach to do that without accessing component instance:
this.set('showComponent', true);
this.render(hbs(`{{if showComponent}}{{my-component}}{{/if}}`));
Then set:
this.set('showComponent', false);

Ember event on window close

When a user closes the browser, I want to run some code before the window gets closed out, because if not it causes problems for other users. Part of the application I'm working on has a random video chat. The room is created by a user and while they're waiting for someone to join they close their browser tab/window and then the room is not closed out correctly and still open for another user to join.
I've seen many examples using beforeunload, but they just aren't working for me with Ember. Maybe I'm missing a more ember way of doing things, or maybe I need to rely on a heartbeat approach?
What I've been trying to do is use the window beforeunload event, but I haven't been having any luck. If there is a better way to go about solving my above problem, I'm all ears!
Right now I bind the method in the setupController such as:
$(window).bind('beforeunload', function() {
console.log('ending chat');
this.endChat();
});
I've also tried this code in the route, and maybe in the view (tried so many things over the past month that I don't remember everything).
UPDATE: Code update
Here is the setupController referring to the controller object instead of the window.
setupController: function(controller, hash){
$(window).on('beforeunload', () => {
controller.hasStarted ? controller.endChat() : controller.send('leaveChat');
});
$(window).on('click', () => {
controller.hasStarted ? controller.endChat() : controller.send('leaveChat');
console.log('you just clicked');
});
}
The window click event fires perfectly, but nothing happens on the beforeunload event - the window just closes normally without firing any action/method.
Where is endChat defined? The way you currently have it written, this.endChat() is scoped to the window. I'm guessing you want it scoped to the controller or route.
If you're using Ember CLI, you can use fat arrow syntax to remain in the outer scope like this:
// routes/application.js
import Ember from 'ember';
export default Ember.Route.extend({
setupController: function () {
$(window).on('beforeunload', () => {
this.endChat();
});
},
endChat: function () {
// do the thing
}
});
If not, then you can do it the old fashioned way:
App.ApplicationRoute = Ember.Route.extend({
setupController: function () {
var _this = this;
$(window).on('beforeunload', function () {
_this.endChat();
});
},
endChat: function () {
// do the thing
}
});
Does that work?
export default Ember.Route.extend({
setupController: function () {
Ember.$(window).on('beforeunload', function(e){
e.returnValue = "hi";
return e.returnValue;
});
}
});

How to reset/restart backbone application

I'm building a little quiz game using backbone.js
Once you get to the end of the quiz you have the option to start again.
How can I achieve this? I've tried recalling the initialize function, as well as the first function that gets fired when you start the game. This is just returning errors. The two calls are success but a subsequent function for rending each question is failing.
I think I need to empty my model/collection. This is my first outing with Backbone, I'm still trying to get my head around how every works.
Any help, greatly appreciated.
You could use the backbone router (don't forget to start it):
So in your game view, you'd have an event which triggered when the start again button was clicked. This event would trigger a function which would redirect the user to a newgame route. You could also setup a function in the router to close your old view. This is important to avoid zombie views
e.g. view
//initialize code
//...
events: {
'click .startAgainButton':'restart'
}
restart: function(e) {
e.preventDefault();
window.location.href = '#/new_game';
}
//rest of view code...
e.g. router
//router code
routes: {
"new_game":"reset"
},
trackView: function (next) {
if (this.current) this.current.close();
this.current = next;
},
//kill zombie views
close: function () {
this.undelegateEvents();
this.$el.off();
this.$el.children().remove();
},
reset: function() {
this.trackView(new View());
}

Cordova 'deviceready' event not firing from within angular .run block

I'm having issues getting 'deviceready' to register from inside of AngularJS. I'm certain this was working before, so I'm not sure what's changed.
If I call 'deviceready' from a global addEventListener, it works, like so:
document.addEventListener('deviceready', function(){
localStorage.deviceReadyGlobal = true;
});
deviceReadyGlobal=true is set. However, if I try to attach this from within Angular, it never fires, like so:
app.run(function(){
document.addEventListener('deviceready', function(){
localStorage.deviceReadyAngular = true;
});
});
deviceReadyAngular is never set. Now, I understand that PhoneGap probably already fired 'deviceready' while Angular was bootstrapping, but according to the PhoneGap docs, that shouldn't matter.
The deviceready event behaves somewhat differently from others. Any
event handler registered after the deviceready event fires has its
callback function called immediately.
Did something change in the behavior of 'deviceready'?
I'm using Cordova 3.3.0 and Angular 1.2.5 currently.
This is how I do it inside my app;
// Create an application module with dependencies
var app = angular.module('myApp', []);
function loadTheApp() {
// Hide splash screen if any
if (navigator && navigator.splashscreen) {
navigator.splashscreen.hide();
}
// Initiate FastClick
FastClick.attach(document.body);
// Boot AngularJS
try {
angular.bootstrap(document, ['myApp']);
} catch (e) {
console.log('errrrrrrrrrrrrrr! ' + e);
}
}
// Listen to device ready
angular.element(document).ready(function() {
if (window.cordova) {
document.addEventListener('deviceready', loadTheApp, false);
} else {
loadTheApp();
}
});
This way if we are inside a device environement then we listen to deviceready event, if not, then we just ignore that event and load our app.
Either way you could also handle it with DOMContentLoaded event handler in javascript way
document.addEventListener("DOMContentLoaded", function() {
//alert("Calling DOMContentLoaded");
document.addEventListener('deviceready', function(){
//alert("Calling onDeviceReady()");
initializeYourApp();
}, false);
});
I've had this issue. For me the problem was having the for cordova.js inside the header.
If you generate a sample project from cordova cli, they have the script tag inside the body.
Once i put it in the body ,like the sample project had it, next to the app-root, i started getting the deviceready event

Categories

Resources