Nativescript - Onesignal Push notifications, Android navigation issue - nativescript

I´m having a hard time understanding what am i missing here when the user receives a push notification and then hits the button in order to see it and navigate to the proper page inside the app, so my code is this and by the way it works very well in ios:
So if the application is android, i use this code below... i receive the content and pass it to a function called handleOpenURL
if (application.android) {
application.on(application.launchEvent, (args) => {
try {
TnsOneSignal.startInit(application.android.context).setNotificationOpenedHandler(new TnsOneSignal.NotificationOpenedHandler({
// notificationOpened: function (result: com.onesignal.OSNotificationOpenResult) {
notificationOpened: function (result) {
const imovelAndroid = JSON.parse(result.stringify()).notification.payload.additionalData;
handleOpenURL(imovelAndroid);
}
})).init();
TnsOneSignal.setInFocusDisplaying(TnsOneSignal.OSInFocusDisplayOption.Notification);
TnsOneSignal.startInit(application.android.context).init();
}
catch (error) {
console.error('error', error);
}
});
}
I´m actually entering the function below, but the problem is when navigating, it simply does not work:
function handleOpenURL(argImovel) {
const precoToNumber = +argImovel['imovel'].preco;
const precoFormated = Number(precoToNumber).toLocaleString("pt-PT", { minimumFractionDigits: 0 });
const navigationOptions = {
moduleName: "detail/detail-page",
context:{ //my context here which is big so i´m not putting it.
}
};
frameModule.topmost().navigate(navigationOptions);
}
Everything works as expected in ios, it is suppose to receive the push, and when the user hits it, the app should navigate to a detail page where the content receive is showned.
What am i missing? thanks for your time, regards.
EDIT
Thanks to Manoj, i fixed the issue adding this to my handleOpenURL function:
setTimeout(() => {
frameModule.topmost().navigate(navigationOptions);
}, 2);

Make sure your Frame is ready for navigation, try logging frameModule.topmost() and see if that is a valid frame.
May be you could try a timeout of 1 or 2 secs and see whether that fixes the issue.

Related

Nativescript angular : handle android back button on different pages

So I use this function to handle android back button :
this._page.on(Page.loadedEvent, event => {
if (application.android) {
application.android.on(application.AndroidApplication.activityBackPressedEvent, (args:AndroidActivityBackPressedEventData) => {
args.cancel = true;
this._ngZone.run(() => {
this.router.navigate(['/parameters']);
});
});
}
})
on different pages (angular components). So on page1.ts I have navigate(['/parameters]) and on page2.ts I have console.log("test"). Problem is wherever I am in the app, pressing back button always do navigate(['/parameters]), also the console.log if i'm on the right page, but it should do console.log only.
It seems to be global, any idea how to override activityBackPressedEvent ?
activityBackPressedEvent is not specific to a page, it's global to your Activity which holds all the pages. Generally, You will not add more than one event listener to this event.
You could do something like below to handle this on page level, probably in app module / main.ts
application.android.on(application.AndroidApplication.activityBackPressedEvent,
(args: application.AndroidActivityBackPressedEventData) => {
const page = frame.topmost().currentPage;
if (page.hasListeners(application.AndroidApplication.activityBackPressedEvent)) {
args.cancel = true;
page.notify({
eventName: application.AndroidApplication.activityBackPressedEvent,
object: page
});
}
});
With above code, activityBackPressedEvent willl be triggered on every page that has a listener.
Now in your page / component in which you want to customise the behaviour you do this,
// Inject Page
constructor(private page: Page) {
this.page.on(application.AndroidApplication.activityBackPressedEvent, this.onBackButtonTap, this);
}
onBackButtonTap(data: EventData) {
this._ngZone.run(() => {
this.router.navigate(['/parameters']);
});
}
I think since you added the handle back button in the event pageLoaded that's why it does not work on other page.
The code that handle back button should be placed in the app starter. I'm using NS Vue & I place this code in my main.js. I think it could be similar in NS angular.
application.android.on(application.AndroidApplication.activityBackPressedEvent, (args:AndroidActivityBackPressedEventData) => {
args.cancel = true;
this._ngZone.run(() => {
this.router.navigate(['/parameters']);
});
});

How to make sure page loads completely in cypress

I am working in cypress.
Steps to repro
I just visit the login page by cy.visit()-spinner is loading
passed the credentials using type-spinner is still loading
click on submit.-spinner is still loading
its throwing error .. why because the login page XHR calls didnt get completed thats why still we can see spinner loading in top and i tried to click the submit button before it gets loaded,may be because of poor network-telling invalid credentials.
I believe you have to wait for the XHR request to get completed and validate the page load or perform other actions.
Here is a sample,
// Wait for the route aliased as 'getAccount' to respond
cy.server()
cy.route('/accounts/*').as('getAccount')
cy.visit('/accounts/123')
cy.wait('#getAccount').then((xhr) => {
cy.get('#loading-bar').should('not.be.visible')
})
Here is a similar solution which I have previously given - Cypress:Is there any way to check invisibility of an element
You check if the button is present and then click on the button.If
describe('check if button present', function () {
it('check for button using CSS Selector', function () {
cy.visit(url)
let found = false
let count=0
while (!found) {
const nonExistent = Cypress.$('.btn-selector')
if (!nonExistent.length) {
found = false
count=count+1
cy.wait(1000)
if(count==60)
{
found = true
cy.log('Element not found after 60 seconds..Exit from loop!!!')
}
}
else
{
found = true
cy.get('.btn-selector').click()
}
}
})
})

Update global variable on scroll event angular 5

I'm working on angular 5 application. I want to update a variable when the page is scrolling, but the problem is when I put console log inside the scope, the variable is updated but in Dom is not.
component:
#HostListener('window:scroll') public windowScrolling(): void {
this.isMenuOpen = false;
console.log(this.isMenuOpen) // false }
DOM:
{{isMenuOpen}} // true
I guess the variable inside the scope becomes local variable but I have no idea how to make it global on scroll event. I really appreciate if somebody has any solution.
**Implement like this**.
ngOnInit() {
window.addEventListener('scroll', function (e) {
this.scroll(e);
}.bind(this), true);
}
scroll(event: any) {
console.log(event)
this.isMenuOpen = false;
console.log(this.isMenuOpen)
}

Firefox extension development: load event only once

I'm developing a kind of kiosk system for firefox. Therefore I need to listen to the load event, everytime a link is clicked and a new page / document is loaded. I used this in the js file to accomplish that:
window.addEventListener('load', function () {
gBrowser.addEventListener('DOMContentLoaded', function () {
alert("load");
}, false);
}, false);
But the event is only fired if i open the new browser window but not on reload or loading another content.
What could I do?
You should probably use nsIWindowWatcher service to do this:
let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
function windowObserver(aSubject, aTopic, aData) {
if (aTopic == "domwindowopened") {
let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
// Do stuff here
}
}
// To start watching windows do this
Services.ww.registerNotification(windowObserver);
// To stop watching windows do this
Services.ww.unregisterNotification(windowObserver);

jQuery Event when Validation Errors Corrected

I have buttons that trigger jQuery validation. If the validation fails, the button is faded to help draw attention away from the button to the validation messages.
$('#prev,#next').click(function (e)
{
var qform = $('form');
$.validator.unobtrusive.parse(qform);
if (qform.valid())
{
// Do stuff then submit the form
}
else
{
$('#prev').fadeTo(500, 0.6);
$('#next').fadeTo(500, 0.6);
}
That part works fine.
However, I would like to unfade the buttons once the invalid conditions have been cleared.
Is it possible to hook into jQuery Validation to get an appropriate event (without requiring the user to click a button)? How?
Update
Based on #Darin's answer, I have opened the following ticket with the jquery-validation project
https://github.com/jzaefferer/jquery-validation/issues/459
It might sound you strange but the jQuery.validate plugin doesn't have a global success handler. It does have a success handler but this one is invoked per-field basis. Take a look at the following thread which allows you to modify the plugin and add such handler. So here's how the plugin looks after the modification:
numberOfInvalids: function () {
/*
* Modification starts here...
* Nirmal R Poudyal aka nicholasnet
*/
if (this.objectLength(this.invalid) === 0) {
if (this.validTrack === false) {
if (this.settings.validHandler) {
this.settings.validHandler();
}
this.validTrack = true;
} else {
this.validTrack = false;
}
}
//End of modification
return this.objectLength(this.invalid);
},
and now it's trivial in your code to subscribe to this event:
$(function () {
$('form').data('validator').settings.validHandler = function () {
// the form is valid => do your fade ins here
};
});
By the way I see that you are calling the $.validator.unobtrusive.parse(qform); method which might overwrite the validator data attached to the form and kill the validHandler we have subscribed to. In this case after calling the .parse method you might need to reattach the validHandler as well (I haven't tested it but I feel it might be necessary).
I ran into a similar issue. If you are hesitant to change the source as I am, another option is to hook into the jQuery.fn.addClass method. jQuery Validate uses that method to add the class "valid" to the element whenever it is successfully validated.
(function () {
var originalAddClass = jQuery.fn.addClass;
jQuery.fn.addClass = function () {
var result = originalAddClass.apply(this, arguments);
if (arguments[0] == "valid") {
// Check if form is valid, and if it is fade in buttons.
// this contains the element validated.
}
return result;
};
})();
I found a much better solution, but I am not sure if it will work in your scenario because I do not now if the same options are available with the unobtrusive variant. But this is how i did it in the end with the standard variant.
$("#form").validate({
unhighlight: function (element) {
// Check if form is valid, and if it is fade in buttons.
}
});

Resources