I have a little bit of a problem with the angular navigator 2
I'm in my detail projects page and I have a component that is in my detail page that will show me the next project.
So in my component I recall the same page which is' /projects/id
when I click in the navigation bar it changes the id well but the content does not change and I do not understand why because I make a router. navigate of my page.
my init controller projectDetail
ngOnInit() {
this.nextProjectId = this.activedRoute.snapshot.queryParams.nextProject;
const id = this.activedRoute.snapshot.params.id
this.projectsService.projectsAll().then( (projects) => {
if (projects[this.nextProjectId]) {
this.nextProject = projects[this.nextProjectId];
} else {
this.nextProject = projects[0];
}
});
this.projectsService.projectFind(id).then( project => this.project = project);
}
my function navigate in component nextProject
nextProjectDetail(id, nextProject) {
const next = parseInt(nextProject, 0) + 1
this.router.navigate(['projects/', id], { queryParams: {nextProject: next }}).then(
function(){
console.log('navigate success');
},
function(){
console.log('navigate failure');
}
);
}
I even tried to use this function in the init of detail projects to see when the url changes but it doesn't work.
this.params.subscribe(params => {
console.log("dfsd");
});
there is another way to refresh the same page in a component on the same page?
thanks
Related
My code works fine when I write in browser localhost:4200/pay;id=1. This show Pay component with credit card fields generated by a external javascript (This javascript script is loaded from this component). But if i come from another component to this, Pay component doesn't show the credit card fields but load external script. How can I fix this?
My code
first.component.ts
let datos = {
id:'6'
}
this.router.navigate(['pay',datos]);
pay.component.ts
ngOnInit(): void {
this.loadScripts();
}
loadScripts() {
this.dynamicScriptLoader.load('2payjs').then(data => {
// Script Loaded Successfully
console.log('All elements loaded successfully')
this.loadElement();
}).catch(error => console.log(error));
}
loadElement(){
let that = this;
let id = this.router.snapshot.paramMap.get('id');
window.addEventListener('load', function() {
// Initialize the JS Payments SDK client.
let jsPaymentClient = new TwoPayClient('AVLRNG');
// Create the component that will hold the card fields.
let component = jsPaymentClient.components.create('card');
component.mount('#card-element');
// Handle form submission.
document.getElementById('payment-form').addEventListener('submit', (event) => {
event.preventDefault();
/// Extract the Name field value
const billingDetails = {
name: document.querySelector('#name').value
};
// Call the generate method using the component as the first parameter
// and the billing details as the second one
jsPaymentClient.tokens.generate(component, billingDetails).then((response) => {
//console.log(response.token);
let data = {
token:response.token
}
}).catch((error) => {
console.error(error);
});
});
});
}
const navigationExtras: NavigationExtras = {
queryParams: {
id: 1,
},
queryParamsHandling: 'merge'
};
this.router.navigate(['pay'], navigationExtras);
you need navigationExtras in order to create params in your router link and able to fetch by another component
Already solved. I just delete window load event listener.
I need to handle push notifications and I am using onesignal for it.
Currently I am handling push notifications in my home screen and I am using react-navigation.
componentDidMount() {
OneSignal.addEventListener('received', this.onReceived);
OneSignal.addEventListener('opened', this.onOpened);
}
componentWillUnmount() {
// OneSignal.removeEventListener('received');
// OneSignal.removeEventListener('opened');
}
onReceived(notification) {
console.log('Notification received: ', notification);
}
onOpened = (data) => {
const { notification: { payload } } = data;
if (payload.additionalData) {
if (payload.additionalData.params) {
this.props.navigation.navigate({
routeName: payload.additionalData.route,
params: payload.additionalData.params,
key: payload.notificationID
});
}
}
}
With this code I am able to navigate to a route specified in the data packet of notifications.
Now the problem I face is, I have a screen and I want to refresh my page, for example call getData(); of that component.
With this approach I am able to navigate to that screen and if I get the notification while I am on that screen. with the help of key, I can navigate to that screen.
Lets say I am going to OrderDetail screen and when I get the notification, It navigates to Order Detail,
Home Screen --> Order Detail
and now If I am inside OrderDetail and if I get the notification, It would be
Home Screen ---> Order Detail ---> Order Detail
...and so on'
How can I handle push notifications in this case?
Possibly... handle the push notification differently on Home and Detail pages.
Say,on Home page, listen to notification when didFocus, and remove the listener when willBlur. So the handler will action only when a user is on Home. And navigate (route) to "Detail" in the notification handler of Home page.
Likewise, on Detail page, listen to notification when didFocus, and remove the listener when willBlur. While the handler simply updates the content when notification is received.
---edit---
Home:
constructor() {
this.props.navigation.addListener(
'willBlur',() => {
OneSignal.removeEventListener('received');
OneSignal.removeEventListener('opened');
}
);
this.props.navigation.addListener(
'didFocus',() => {
OneSignal.addEventListener('received');
OneSignal.addEventListener('opened');
}
);
}
// handler implementation is the same
Detail:
//same lifecycle implementation
// but different handler
onOpened = (data) => {
const { notification: { payload } } = data;
if (payload.additionalData) {
if (payload.additionalData.params) {
this.setState(paramsUsedByDetail: payload.additionalData.params);
}
}
I am using a global provider to open pages by passing the navigation controller from the page to the provider method. Is there any other way to do this better?
Main objective is not to repeat my self. Open page method I use in the globalProvider.ts is as follows. currentActive page is stored in a variable of the provider in case user logins to the app he will be redirected to the last active page (currentActive)
globalProvider.ts
openPage(navCtrl, page, params, setActive = true) {
this.showLoading();
if (setActive) {
this.currentActive = { root: page, params: params };
} else {
this.currentActive = { root: 'HomePage', params: null };
}
navCtrl.setRoot(page, params).then(res => {
if (!res) {
this.showError('Please login to view page!');
navCtrl.setRoot('LoginPage', {
activePage: this.currentActive.root
}).then(res => {
this.hideLoading();
}).catch(err => {
this.hideLoading();
});
}
this.hideLoading();
}).catch(error => {
this.hideLoading();
});
}
I don't think there is anything bad with this practice. I also do similar logic to avoid repeating the show loading and hide loading logic in every page.
However I also keep one more parameter, to help me decide if the page should be set as root or should be pushed on current stack.
This also helps me to track page views for analytics from a central place.
I have two forms, one is called profile, the other is settings. I'm using introjs to have a guided tour through these two forms. If I only move forward through the tour using the introjs 'Next Step' button there are no issues (first image). But, if I use the browser back or forward button, my forms look like the second image.
Code on profile page that utilize introjs:
runTour() {
if (this.state.showTour === true) {
const tourObj = {
userId: Meteor.userId(),
page: 'profile',
};
introJs.introJs().setOption('doneLabel', 'Next step').start().oncomplete(()
=> {
changeIntroTour.call(tourObj);
browserHistory.push('/user/settings');
})
.onexit(() => {
changeIntroTour.call(tourObj);
});
}
}
componentWillReceiveProps(nextProps) {
this.existingSettings(nextProps);
if (nextProps.intro.length > 0) {
this.setState({
showTour: nextProps.intro[0].profileTour,
}, () => {
this.runTour();
});
}
}
The issue was I was not calling introJs.exit() on componentWillUnmount. This was keeping my instance of introJs running from one component to the next which caused the bug.
i'm currently working on a project with vue.js and vue-router. I got a vue in which I display some news, and I got thoses news from an API (it's kind of a blog).
I'm currently loading thoses news inside the router.data to set the data for the component, as said here. It's working great, no problems.
But my problem is that I want to animate the apparition of the news when I go to this view. I've tried using the ready property from the component, but it's called before the router.data has finished getting the news, which result in errors in animation, because there aren't any elements.
How can i trigger the animations once the news I fetch are fully rendered inside the DOM ?
Here is the code of my component:
export default {
name: 'News',
data: function () {
return {
news: []
}
},
route: {
data: function (transition) {
console.log('data hook')
return api
.getPostsByLimit(4, 1)
.then(function (posts) {
for (var i = 0; i < posts.length; i++) {
var post = posts[i]
post.formatedDate = moment(post.date).format("D MMM. YYYY")
post.dateTime = moment(post.date).format("YYYY-MM-DD")
if(post.news_artist_related) {
post.news_artist_related = JSON.parse(post.news_artist_related)
post.news_artist_related.type = slugify(post.news_artist_related.type)
post.news_artist_related.slug = slugify(post.news_artist_related.slug)
}
}
return posts
})
.then(news => ({news}))
}
},
ready: function () {
console.log('Ready hook')
animateNewsApparition()
}
}
From the docs:
When resolved, the component will also emit a 'route-data-loaded' event.
So:
events: {
'route-data-loaded': function() {
animateNewsApparition()
}
}