I am currently working on an Ionic 2 app which requires authentication each time the app moves into the background and resumes.
import { ModalController } from 'ionic-angular';
#Component({
selector: 'item-details',
templateUrl: 'item-details.html'
})
export class ItemDetailsPage {
private modalCtrl: ModalController) {
}
ionViewDidLoad() {
this.platform.resume.subscribe(() => {
let modal = this.modalCtrl.create(LoginModalPage, true);
modal.present();
});
}
The issue I am having is that when the app resumes, it is correctly detects that it has resumed but then gives the error:
EXCEPTION: Attempted to assign to readonly property
When I use web inspector attached to the simulator it seems to imply the modal is undefined but I am unsure why.
This is how you have created modal
let modal = this.modalCtrl.create(LoginModalPage, true);
But from docs, instance is created with create(component, data, opts) where data is an object. In your case it is a boolean. So you need to pass an object. Here is the doc
Related
I’m just starting with Forge and JIRA apps development, I need to open a ModalDialog when an issue changes its state to “Done” (either by dragging it to the Done column or by changing its status in the issue panel). I don’t know where to start, I tried clonning the jira-issue-activity-ui-kit starter but I don’t get where the modal should open, any ideas? Thanks
This is the code I've tried:
const DONE = 'Done';
export async function run(event, context) {
console.log('Hello World!', event, event.changelog.items);
// if the issue is solved (status changed to Done)
if (event.changelog.items.some(function changedToPreferredStatus(change) {
return statusChangedTo(change, DONE);
})) {
let description = event.issue.fields.summary;
// OPEN MODAL DIALOG HERE
}
}
function statusChangedTo(change, to) {
return change.field === 'status' && change.toString === to;
}
I am going through the documentation on electronjs and i've just gotten to the part about notifications and adding clicking events. I added the notification.onclick property but when i click on the notification after running the app, nothing gets shown on the console. This is the code in the renderer.js file.
let myNotification = new Notification('Title', {
body: 'Notification from the Renderer Process'
})
myNotification.onclick = () => {
console.log("Notification clicked")
}
Can anyone tell me where i am going wrong?
We are trying to use the plugin "Xam.Plugin.Geolocator" in our Xamarin Forms project. The project is currently IOS only.
Our app returns a list of business based on the device users current location. We hit an API to return our JSON formatted list data and the API is functioning correctly.
We would like the list to update whenever the user pulls down, changes tab and when the page initially loads but currently this is only working once or twice in around 100 attempts. I've not found a pattern yet to why it's failing, or indeed when it works.
We set App Properties when the page loads, the tab is selected and the user refreshes like this -
public async void GetLocation()
{
try
{
locator = CrossGeolocator.Current;
if (locator.IsGeolocationAvailable && locator.IsGeolocationEnabled)
{
var position = await locator.GetPositionAsync();
App.Current.Properties["Longitude"] = position.Longitude.ToString();
App.Current.Properties["Latitude"] = position.Latitude.ToString();
}
else
{
await DisplayAlert("Location Error", "Unable to retrieve location at this time", "Cancel");
}
}catch(Exception e)
{
await DisplayAlert("Location Error", "Unable to retrieve location at this time","Cancel");
}
}
We call the above method in the three areas
1) when the page is loaded
public NearbyPage()
{
InitializeComponent();
GetLocation();
SetNearbyBusinesses();
NearbyBusinesses = new List<NearbyBusiness>();
SetViewData();
SetViewVisibility();
}
2) when the tab is clicked
protected override void OnAppearing()
{
base.OnAppearing();
GetLocation();
SetNearbyBusinesses();
NearbyLocationsView.ItemsSource = NearbyBusinesses;
NoLocationsView.ItemsSource = UserMessages;
SetViewVisibility();
}
3) when the user pulls down to refresh
public void RefreshData()
{
if (!CrossConnectivity.Current.IsConnected)
{
NoInternetMessage.IsVisible = true;
return;
}
GetLocation();
NoInternetMessage.IsVisible = false;
SetNearbyBusinesses();
NearbyLocationsView.ItemsSource = NearbyBusinesses;
NoLocationsView.ItemsSource = UserMessages;
SetViewVisibility();
_analyticsService.RecordEvent("Refresh Event: Refresh nearby businesses", AnalyticsEventCategory.UserAction);
}
Can anyone shed some light on what we're doing wrong or have experience with this plugin that can help us resolve this issue?
Thank you
EDIT
By "work", i mean that we'd like it to hit our API with the users current location data and return new results from the API every time the user pulls down to refresh, the page is loaded initially or when they press on a specific tab. Currently it works occasionally, very occasionally.
We can't debug with a phone connected to a macbook, as since we installed the geolocator plugin the app always crashes when connected. The app seems to work ok when deployed to a device, apart from the location stuff. We're currently deploying to test devices via Microsofts Mobile Centre.
Ok, so with the debugger always crashing and being unable to see any stack trace etc we took a few shots in the dark.
We've managed to get this working by adding async to our method signatures down through our code stack. This has resolved the issue and the geo location and refresh is working perfectly.
For example when we changed the above method 3. to refresh the data, it worked perfectly.
public async Task RefreshData()
{
if (!CrossConnectivity.Current.IsConnected)
{
NoInternetMessage.IsVisible = true;
return;
}
GetLocation();
NoInternetMessage.IsVisible = false;
SetNearbyBusinesses();
NearbyLocationsView.ItemsSource = NearbyBusinesses;
NoLocationsView.ItemsSource = UserMessages;
SetViewVisibility();
_analyticsService.RecordEvent("Refresh Event: Refresh nearby businesses", AnalyticsEventCategory.UserAction);
}
We refactored more of that code but adding async was what got it working.
I hope this helps someone else save some time.
Lately, I have been adding push notifications capability on my app. I am using FCN plugin found on this link and I developing using Ionic 2 framework. The notifications get delivered but when I tap on it it just opens the homepage of the app, and not the inner page that I need.
I have used this code
declare var FCMPlugin;
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = HomePage;
horoscopePage:any = HoroscopeHomePage;
#ViewChild(Nav) nav: Nav;
**********************
FCMPlugin.onNotification(function(data){
if(data.wasTapped){
//Notification was received on device tray and tapped by the user.
if(data.topic =="horoskopi" && data.type=="list"){
console.log( JSON.stringify(data) );
this.nav.push(this.horoscopePage);
}
}else{
if(data.topic =="horoskopi" && data.type=="list"){
console.log( JSON.stringify(data) );
this.nav.push(this.horoscopePage);
}
}
});
});
Somehow this line of code this.nav.push(this.horoscopePage); doesn't do anything
When I use NavController instead it gives me this error:
MyApp_Host.html:1 ERROR Error: No provider for NavController!
at injectionError (core.es5.js:1231)
at noProviderError (core.es5.js:1269)
at ReflectiveInjector_._throwOrNull (core.es5.js:2770)
at ReflectiveInjector_._getByKeyDefault (core.es5.js:2809)
at ReflectiveInjector_._getByKey (core.es5.js:2741)
at ReflectiveInjector_.get (core.es5.js:2610)
at AppModuleInjector.NgModuleInjector.get (core.es5.js:3578)
at resolveDep (core.es5.js:11039)
at createClass (core.es5.js:10903)
at createDirectiveInstance (core.es5.js:10723)
You can add public navCtrl: NavController into constructor then change code as
this.navCtrl.push(this.horoscopePage);
Well after I took a look at the official documentation of Ionic, I found out that we can't use NavController in app.component.ts because you can't inject NavController because any components that are navigation controllers are children of the root component so they aren't available to be injected. For more click here.
The reason that I was unable to push a new Page inside FCM.onNotifications() functions was that it changed the scope of application. The solutions was simple: just use the arrow function:
FCMPlugin.onNotification(
(data)=>{
if(data.wasTapped){
//do something
}
else {
//do something
}
});
I have an app that is listening in background and when the user clicks "send" it displays a dialogue. However I need to bring my app to foreground so the user answers some questions before letting the message go. but I haven't been able to do this, this is the code in my SendListener:
SendListener sl = new SendListener(){
public boolean sendMessage(Message msg){
Dialog myDialog = new Dialog(Dialog.D_OK,
"message from within SendListener",
Dialog.OK,Bitmap.getPredefinedBitmap(Bitmap.EXCLAMATION),
Dialog.GLOBAL_STATUS)
{
//Override inHolster to prevent the Dialog from being dismissed
//when a user holsters their BlackBerry. This can
//cause a deadlock situation as the Messages
//application tries to save a draft of the message
//while the SendListener is waiting for the user to
//dismiss the Dialog.
public void inHolster()
{
}
};
//Obtain the application triggering the SendListener.
Application currentApp = Application.getApplication();
//Detect if the application is a UiApplication (has a GUI).
if( currentApp instanceof UiApplication )
{
//The sendMessage method is being triggered from
//within a UiApplication.
//Display the dialog using is show method.
myDialog.show();
App.requestForeground();
}
else
{
//The sendMessage method is being triggered from
// within an application (background application).
Ui.getUiEngine().pushGlobalScreen( myDialog, 1,
UiEngine.GLOBAL_MODAL );
}
return true;
}
};
store.addSendListener(sl);
App is an object I created above:
Application App = Application.getApplication();
I have also tried to invoke the App to foreground using its processID but so far no luck.
i have managed to achieve something similar to what you're describing but the difference is, my dialogs are displayed asynchronously, which might actually be easier... so in your case..
the first i could suggest you try is get the event lock before pushing the screen, ala:
synchronized(Application.getEventLock()){
final UiEngine ui = Ui.getUiEngine();
ui.pushGlobalScreen(theScreen, 1, UiEngine.GLOBAL_MODAL);
}
I would also just create a custom class of type MainScreen and push that instead of plain Dialog.
There, that's better (now with code formatting).
public class MYSendListener implements SendListener {
private UiApplication _myApp;
public MySendListener(UiApplication myApp) {
_myApp = myApp;
}
public boolean sendMessage(Message m) {
...
_myApp.requestForeground();
}
}
Cache your app instance inside your send listener when you construct it, and use that when sendMessage is fired.
Application.getApplication() only gets you the app of the calling thread.