Ionic 2 - Prevent exit app on hardware back button - ionic2

In my Ionic 2 App the hardware back button (android, windows) should work like he is doing it on default, with one exception: He should not exit the app if there is nothing to go back.
I know I can do it like this:
platform.ready().then(() => {
platform.registerBackButtonAction(() => {
// Default action with the exception here
},);
});
But how must I do it exactly now, to make it work as default but with this one exception? In the ionic 1 docs of that function there are the priorities of the different cases. But I think that got changed in ionic 2!? Because in the ionic 2 docs there are not these priorities. I have tried to set the priority to 99, because then everything should work as default. But now the sidemenu can not be closed anymore and thats why I think the priorities of ionic 1 have been changed, because in the ionic 1 docs the priority of the sidemenu is 150 and thats why my function should be ignored. Someone can help me with it?

constructor(public nav: NavController, private platform: Platform, public menu: MenuController) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need
platform.registerBackButtonAction(() => {
if(this.menu.isOpen()){
this.menu.close()
}
else if(this.nav.canGoBack()){
this.nav.pop();
}else{
//don't do anything
}
});
});
}

Just set the property navExitApp to false in file app.module.ts at imports
IonicModule.forRoot(YourApp, {
navExitApp: false
}),
Easy! :)

Related

Ember Mirage: route answered only if debugger is ran

I'm facing a weird issue with Ember mirage. I try to use it inside an integration test.
The code looks like this:
moduleForComponent('editors/steps/call-handler', 'Integration | Component | editors/steps/call handler', {
integration: true,
beforeEach: function () {
startApp();
this.server = startMirage();
...
},
afterEach: function () {
this.server.shutdown();
}
});
test('...', function (assert) {
...
this.server.post('/projects/12/actionwords/1/switch/', () => {
assert.ok(true, "switch route is called");
return {
... some JSON data
}
});
this.render(hbs`{{editors/steps/call-handler
...
}}`);
... and then some manipulation of the component
});
Now the test fails when I run it this way. The weird part is, if I place a debugger just before rendering the component, the test will pass.
I guess there are some timeout issues sooner or later that the debugger hides. Usually, I would only render the component in a callback to ensure the route has been correctly setup but this.server.post returns nothing not has any callbacks (except if I missed something in the doc).
I also tried setting the timing option (just in case) but it doesn't change anything (as expected).
I also tried to add an homemade sleep function to wait one second without the debugger and then the tests work fine. Of course if I can have a clean way to get them working, I'd prefer ;)
Did anyone face the same kind of issues and found a way to solve it ?
Best regards,
Vincent

How to remove these deprecation on console on ember^2.0

while refreshing my site i am always getting some deprecation like this on console :
A property of <Ember.OutletView:ember666> was modified inside the didUpdate hook. You should never change properties on components, services or models during didUpdate because it causes significant performance degradation. [deprecation id: ember-views.dispatching-modify-property]
How to remove these deprecation on console on ember^2.0
I am not using Ember CLI.
Usually it means, that you need to do the work inside the didReceiveAttrs method, rather than the didUpdate. However, it you must have it in didUpdate, you can do something like this:
didUpdate() {
Ember.run.scheduleOnce('afterRender', this, => {
// some code
});
}
However it most likely will do some rendering twice (however it already does it twice - hence the deprecation).
Romans solution worked well for me, except for some syntax problems. I needed to set a default value to a child component. Heres the code:
initDefValue: function() {
const valEmpty = Ember.isEmpty(this.get("value"));
if (valEmpty) {
Ember.run.scheduleOnce('afterRender', this, () => {
this.sendAction("initValue", this);
});
}
}.on("didReceiveAttrs"),

Ember Integration Test Doesn't See the DOM

import Ember from 'ember';
import startApp from '../../helpers/start-app';
var App;
module('Integration | Authentication | Abilities', {
integration: true,
setup() {
App = startApp();
},
teardown() {
Ember.run(App, 'destroy');
}
});
test('Only SuperUsers, Researchers and AccountHolders can see messages', function(assert) {
visit('/');
assert.equal(find('div').text(), 'fsfsfd');
});
This is an integration test I'm trying to get working so I can test basic user interaction in our ember-cli app. The problem is that this simple test does only returns empty strings whenever I search the DOM. It is not hitting an unauthorized page or anything it's just returning nothing from any testHelpers. currentURL, currentPath return undefined.
Am I missing something absolutely fundamental in my understanding of how integration tests work?
I'm trying to test how ember-can gives and denies permissions to users based on their title. However, I may as well just be testing whether or not the logo shows up in the right corner because I can't see anything on the page at the moment.
I think what you're missing is that tests are asynchronous. Transitions involve promises (typically loading models) so you need to wait for the visit to complete. You can use the andThen helper:
test('Only SuperUsers, Researchers and AccountHolders can see messages', function(assert) {
visit('/');
andThen(function() {
assert.equal(find('div').text(), 'fsfsfd');
});
});
Here's more info in the guides
I'm posting because it turns out the problem was the way our website had been set up with a rootURL. I had to put this line inside our startApp.js file: setResolver(Ember.DefaultResolver.create({ namespace: "/cli/ea/" }));
It looks like the resolver was taking me to localhost:4201/ which is not actually going to be used because we are proxying from rails (which is localhost:3000). Therefore, nothing was coming back from any DOM interaction because there was no route and no template set. currentURL and other helpers returning undefined I guess was the only piece that was unusual in hindsight.

How to trigger scroll event in acceptance test

I need to trigger window scroll event to test infinite scrolling, I've tried to use triggerEvent, but it seems that I missing something and it doesn't work. I'm using Ember 2.0 and list is rendered inside the component if it matters. Test fails on last 2 assertions, scroll position doesn't change after triggering event
test 'loads more items when scrolling', (assert) ->
visit '/locations/1'
andThen ->
assert.equal(find('.items-list li').length, 30)
find(window).scrollTop(10000)
triggerEvent(window, 'scroll')
andThen ->
assert.ok(find(window).scrollTop() > 0, 'window should scroll')
assert.ok(find('.items-list li').length > 30, 'should load more items after reaching threshold')
Has anyone successfully triggered scroll event in their tests?
Finally I could make it work! Used #ember-testing-container instead window.
The code below was what worked for me:
andThen(() => {
Ember.$('#ember-testing-container').scrollTop(10000);
});
triggerEvent(Ember.$('#ember-testing-container'), 'scroll');
andThen(() => {
assert.ok(Ember.$('#ember-testing-container').scrollTop() > 0, 'window should scroll')
});
With ember-infinity you also need to scroll down the body before starting the test:
Ember.$('body').scrollTop(2000);
I have an possible answer for this.
Try
triggerEvent('.skip-button', 'scroll', [{isInTestEnvironment:true}] ).then...
Say .skip-button is a selector within your ember app, but it could be any other one.
The scroll event is detected by the ember app, as if it actually doesn't scroll anything... this is why I pass a isInTestEnvironment:true param to indicate the ember app I simulated a user scroll.
Not an ideal solution, but far better than no test at all.

Can't get ember bindings to work as documented

I am following the documentation on emberjs.com, but can't get the first bindings example to work.
I created a jsfiddle to demonstrate. What am I missing?
Ember.js uses the concept of a RunLoop to allow bindings, observers and so on.
The problem with the example is that by setting a (bound) property and immediately getting the value via console.log no event is fired which would trigger the RunLoop and therefore synchronize the changes. There are 2 excellent blog posts about the RunLoop: Part 1 and Part 2. Although they target Sproutcore, the concept is about the same for Ember.js.
There are two ways to make your example work.
Force synchronisation via Ember.run.sync()
As the docs state, invoking Ember.run.sync() ... is a useful way to immediately force all bindings in the application to sync. This leaves the code like this, see http://jsfiddle.net/pangratz666/cwR3P/
App = Ember.Application.create({});
App.wife = Ember.Object.create({
householdIncome: 80000
});
App.husband = Ember.Object.create({
householdIncomeBinding: 'App.wife.householdIncome'
});
// force bindings to sync
Ember.run.sync();
console.log(App.husband.get('householdIncome')); // 80000
// Someone gets raise.
App.husband.set('householdIncome', 90000);
// force bindings to sync
Ember.run.sync();
console.log(App.wife.get('householdIncome')); // 90000​
Or the second option is to ...
Show the values in a view
Showing the properties in a view handles all the RunLoop stuff for you, see http://jsfiddle.net/pangratz666/Ub97S/
JavaScript:
App = Ember.Application.create({});
App.wife = Ember.Object.create({
householdIncome: 80000
});
App.husband = Ember.Object.create({
householdIncomeBinding: 'App.wife.householdIncome'
});
// invoke function in 3000ms
Ember.run.later(function() {
// someone gets a raise
App.husband.set('householdIncome', 90000);
}, 3000);​
Handlebars (the view):
<script type="text/x-handlebars" >
Wifes income: {{App.wife.householdIncome}}<br/>
Husbands income: {{App.husband.householdIncome}}
</script>​
You'll need to call Ember.run.sync(); after setting up your bindings to give Ember's run loop a chance to sync before your log statements. This is a handy technique for testing with Ember as well, but isn't typically needed in Ember apps themselves.