I have a modal using the modal service:
import { ModalDialogService } from "nativescript-angular/directives/dialogs";
private modal: ModalDialogService,
I can call a modal, for example
this.modal.showModal(MyModalComponent, options).then(res => {
// console.log(res);
});
Now I want to close the modal, but not from within the modal itself. This already works in iOS:
const page = topmost().currentPage;
if (page && page.modal) {
page.modal.closeModal();
} else {
console.log("error closing modal!!!!");
}
But running this with Android, it will always goes to the error console.log, resulting the modal not being closed. The user can still close it (the modal has a close button), but I also want to programaticly close the modal.
That's not the way how you should do it in Angular. Inject ModalDialogParams and use the closeCallback method.
constructor(private modalDialogParams: ModalDialogParams) {}
onCloseButtonTap() {
this.modalDialogParams.closeCallback();
}
I had a similar issue, what I ended up doing was implementing an interface to activate the closeCallback on the modal parameters from the other class. Here is a playground showing what I did https://play.nativescript.org/?template=play-ng&id=q1mDZI&v=6
Related
I am trying to hide app content when the user tries to navigate away from the app, like how banking apps or outlook works. I am using appstate inactive for ios, and appstate blur+focus for android. This works on Android when the user pulls down the notification panel or swipes up to multitasking tray or home through a gesture.
However, if the android phone has soft buttons for navigation instead of gestures, the app doesnt show the security screen on blur. I suppose react native loses control of the app too soon for that to happen. The blur event is still triggered, but the UI remains unchanged.
I have a useEffect in a custom hook that changes the state on blur, which triggers the UI update;
const [appStateVisible, setAppStateVisible] = useState(true);
const appState = useRef(AppState.currentState);
useEffect(() => {
const androidFocusSubscription =
Platform.OS === 'android' &&
AppState.addEventListener('focus', () => {
setAppStateVisible(true);
});
const androidBlurSubscription =
Platform.OS === 'android' &&
AppState.addEventListener('blur', () => {
setAppStateVisible(false);
});
return () => {
if (androidFocusSubscription && androidBlurSubscription) {
androidFocusSubscription.remove();
androidBlurSubscription.remove();
}
};
}, []);
return appStateVisible;
And then on App.tsx, I am calling this hook to decide whether to show the security image instead of the actual app content.
The alternative would be to use FLAG_SECURE in the java code to show a white screen when the app isnt active, but I want to show a custom screen with the app logo instead of a white screen.
Any help would be greatly appreciated. Thank you.
The app closes unexpectedly in ionic.
i'm using ionic v-5 and codova v-10.
i was trying to close the modal when the android hardware back button is pressed, but the app closes completely unexpectedly instead. i tried with the surfing the ionic forums for cordova the solution there dint worked for me.
i tried this piece of code in both app component and the modal component
this.platform.backButton.subscribeWithPriority(10, () => {
console.log('angular Handler was called!');
this.modal.dismiss();
});
and
this.platform.backButton.subscribe(() => {
console.log("back button pressed")
if(this.modal.top())
{
this.modal.dismiss();
}
});
Even though trying these both code it didn't worked still the app was closed when the back button is pressed.
I'm trying this from very long time but not able find the solution!
put this code inside function initializeBackButtonCustomHandler()
and call function inside initializeApp() this function
this.platform.backButton.subscribeWithPriority(0, async () => {
this.alert.dismissLoading();
try {
const element = await this.modalCtrl.getTop();
if (element) {
element.dismiss();
return;
}
} catch (error) {
}
});
I have an app built in Nativescript-Vue where detail pages are shown in modals.
I use the method $showModal() to open a modal, but when I press the hardware back button on an Android device before the modal is rendered, the app crashes and it's giving me the following error.
If I wait a second, it works just fine.
TypeError: Cannot read property 'nativeView' of undefined
Should I override the back functionality to wait before the modal is fully rendered?
I think NativeScript-Vue might be trying to access a non-existent ref.
If you want to override it manually you could adding something like the following to your modal:
import * as app from 'tns-core-modules/application'
export default {
data: {
...
rendered: false
},
methods: {
onBackButtonPress (message) {
if (!this.rendered) return
app.android.off(app.AndroidApplication.activityBackPressedEvent, this.onBackButtonPress)
this.$modal.close(message)
}
},
created () {
app.android.on(app.AndroidApplication.activityBackPressedEvent, this.onBackButtonPress)
},
mounted () {
this.rendered = true
}
}
I'm not sure though whether the listener that's added in the created method will be added in time to prevent the crash.
Android devices has back button on menu toolbar. I want to disable the possibility when i login to my app and click on that back button to route on login page.
I want if user click on back button after login then i close the app.
Here is my initial code for routing below.
if (token) {
this.router.navigate(['/main-tabs/tabs/dashboard'])
} else {
this.router.navigate(['/login']).then();
}
I've tried many other answers but none of them really works for me. But this one works :
To disallow the login from going 'back' to the authenticated page after logged out, just do something like this in your app-routing.module.ts :
{
path: 'home',
loadChildren: './home/home.module#HomePageModule',
canActivate: [LoggedAuthGuard]
}
The same for the opposite (to prevent going back into login page with back button) :
{
path: 'login',
loadChildren: './login/login.module#LoginPageModule',
canActivate: [NotLoggedAuthGuard]
}
And both LoggedAuthGuard and NotLoggedAuthGuard must implement CanActivate. Sample code as below (with Promise, but it also works with boolean return) :
import { Injectable } from '#angular/core';
import {CanActivate} from "#angular/router";
import {Storage} from "#ionic/storage";
#Injectable({
providedIn: 'root'
})
export class LoggedAuthGuard implements CanActivate {
constructor(protected storage: Storage) { }
async canActivate() {
return (await !!this.storage.get('access_token'));
}
}
For the NotLoggedAuthGuard you just returns the opposite of LoggedAuthGuard.
async canActivate() {
return (await !this.storage.get('access_token'));
}
Hope this helps.
This answer provides a solution for removing the login page from the browser's history by replacing it with a page, that the user was navigated to after successful login. It might be a good and quick solution to:
I want to disable the possibility when i login to my app and click on
that back button to route on login page.
What I understood from your question is after user login, You don't want to navigate to login page if back button is clicked. If I understood your question correctly you can try below solution.
one approach is changing root page
this.navCtrl.setRoot(HomePage);
or
You can achieve this by removing page from stack after successful transition. Place below code inside Login success method
let currentIndex = this.navCtrl.getActive().index;
this.navCtrl.push(DestinationPage).then(() => {
this.navCtrl.remove(currentIndex);
});
Hope this helps you.
I think you can do like that :
this.platform.backButton.subscribe((()=>{
if(this.router.url == <insertpathhome>)
{
this.platform.exitApp();
}
else{
//go back
}
});
I am facing a very weird issue with an app which has been working fine and after upgrading to react-navigation v2 has started to have the issue.
Anywhere within the app, the Back Button on Android closes the app and moves it back to the suspended apps.
I have tried many things in terms of handling the back behaviour manually, downgrading some of the packages etc but none of them worked.
Here is my package.json file:
I had the same issue and these are what I found:
https://github.com/react-navigation/react-navigation/issues/4329
and
https://github.com/expo/expo/issues/1786
A temporary solution is mentioned, which is to downgrade firebase to 5.0.3, which works for me.
The issue is with the npm firebase package. There are two ways to fix this.
As mentioned in the other answers, downgrade firebase to 5.0.3
Change the way in which you import firebase. This method will be a lot
easier.
Use:
import firebase from "#firebase/app";
import "firebase/auth";
import "firebase/database";
Don't use import * as firebase from "firebase"; or import firebase from "firebase";
See this GitHub issue for more details.
The solution of downgrading Firebase worked for me too but I had to downgrade to Firebase 4.13.1 as with 5.0.3 I was still facing the issue.
If you are using react-navigation v2, take a look this documentation.
You can also use react-navigation-backhandler for an easy-to-use solution.
Converting this import statement fixed my issue
import Firebase from '#firebase/app' // The issue got fixed after adding #
import 'firebase/auth'
import 'firebase/database'
import 'firebase/storage'
Without the # the backbutton was exiting the user from application
I have faced the same issue, it seems like the implementation of Backhandler.android.js is not correct, you can find the file here node_modules/react-native/Libraries/Utilities/BackHandler.android.js , in this file const subscriptions = Array.from(_backPressSubscriptions.values()).reverse(); piece of code always returns an array of length 0, that's why the invokeDefault variable always stays true and closes the app, you can fix it by handling the back button behavior via your own implementation.
In Navigation Service add this method
import { NavigationActions, StackActions } from 'react-navigation';*
let navigator;
function setTopLevelNavigator(navigatorRef) {
navigator = navigatorRef;
}
function pop() {
navigator.dispatch(StackActions.pop());
}
export default {
pop,
setTopLevelNavigator
};
You need to set the top level navigator in your app.js, like this int render method's return statement
<AppNavigator //Replace it with your navigator
ref={navigatorRef => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
onNavigationStateChange={(prevState, currentState) => {
this.setState({ currentState });
}}
/>
To handle the Back button functionality add these things in your app.js
import NavigationService also
import {
BackHandler,
DeviceEventEmitter
} from 'react-native';
In componentDidMount add these
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleHardwareBack);
}
In componentWillUnmount add these
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress',this.handleHardwareBack);
}
Now handling the hardware back button
handleHardwareBack = () => {
if (!isUndefined(this.state.currentState)) {
const mainRouteIndex = this.state.currentState.index;
const mainRoute = this.state.currentState.routes[mainRouteIndex];
const subRouteIndex = mainRoute.index;
if (subRouteIndex === 0) {
console.log(
'the screen name is ----> ',
mainRoute.routes[subRouteIndex].routeName
);
this.toggleExitModal(); //you can place any dialog if you want to show
return true;
}
NavigationService.pop();
return true;
}
console.log('Back Button is handled in the respective page seperately');
};
return true tell that we are going to handle the back button functionality manually, return false will lead to exits the app as by default it is Hardware back button closes the app :(
Hope this will help you
Well i am using firebase 5.5.5 i don't have any problem with navigation , I think you need to create your stack navigator to use the back butoon properly , I have given a example of it. pages are imported also i have not attached the screen importing code
import { createSwitchNavigator, createStackNavigator } from 'react-navigation';
const Drawer = createDrawerNavigator(
{
BrowseQuestion: BrowseQuestion,
BrowseCategory: BrowseCategory,
}
);
const Loginstack = createStackNavigator({
Login: LoginScreen,
Forgot: ForgotPassword,
Signup: SignupScreen,
})
export default createSwitchNavigator({
Login : Loginstack,
Account: Drawer,
},
{
initialRouteName: 'Login'
}
);