Ionic event to identify user came from navCtrl.pop() - javascript

I have three pages named as page1,page2 and page3
and their navigation will be page1->page2->page3
How we can identify on page2 that user came on this page via NavController Push or Pop function.
I just want to trigger a function on page2 only if they perform some action on page3 and redirected to page2 via navCtrl.pop() function.
I know i can put condition in ionViewWillEnter for last view name from nav stack, Because it will be fired everytime user be on page2. But If there is any other alternate or good way to do this. Please let me know
Thanks

Identifying if we came to a page using push is easy as it is the standard way of passing a parameter from parent to child in navCtrl.push(PageName, parameters)
I think what you are asking is how to do the opposite: pass a value back from child to parent.
Below is a solution for this (see this link for details):
In parent, instead of the normal push function, create a new promise, and in the then part, you can get a parameter back from the child.
In child, after pop() call its then, and pass a parameter through the resolve of the promise that you initially created to the parent.
Parent
new Promise((resolve, reject) => {
this.nav.push(ChildPage, {resolve: resolve});
}).then(data => {
// process data
});
Child
this.nav.pop().then(() => this.params.get('resolve')('some data'))
I have used the above solution many times. There is also this alternative solution, but I haven't tested it myself:
https://forum.ionicframework.com/t/solved-ionic-navcontroller-pop-with-params/58104/3

I'm using globalThis['datatoinput'] to input my data and then using ionViewDidEnter on my parent page to read globalThis['datatoinput']

Related

How do I wait for users to click on certain buttons in component, then return a value from that in a function depending on which button was pressed?

I have an overlay component that appears when a user clicks on certain things in my page, and in this overlay it gives a warning and 2 buttons, one for yes and the other for no. What I want is to create a function that'll serve this component, and then it will wait for the user to respond, and subsequently return true or false based on what button was pressed. This boolean result can then be used to further progress to other code.
This is what I have tried already. It uses promises rather than rxjs observables.
A component will call this function to bring the overlay from the service, eg this.service.promptUser().then(res => if (res === true) { doSomething() }).
In the service:
didContinue: boolean = null;
async promptUser() {
this.showOverlay.next(true) //BehaviourSubject when true brings the popup
await waitForUser();
const decision = this.didContinue;
this.closeOverlay(); //sets didContinue back to null
return decision
}
The didContinue is a property inside of the service to indicate whether they have clicked yes or no using a boolean. Otherwise it will remain null. The click events from the overlay component will set the property didContinue to true or false.
The waitForUser function to wait for the user's input:
async waitForUser() {
while (this.didContinue === null) {setTimeout(() => {}, 50};
}
Currently it'll get stuck at the waitForUser() function but the popup will have not rendered at that stage, so the user can't input anything, the didContinue property will never change, and the application will freeze.
Please do send it forward if you know of an existing solution, I miss a lot of things with my google-foo. I am currently still new to Angular.
Create a service that will handle the result
inject service in your component where you want to use it like this
constructor(public popService: popService) { } // create functions accordingly in service
Call service method with the help of constructor on click() event like this
<button (click)="popService.success()">Done
<button (click)="popService.cancel()">Done
i hope this will help, let me know if you need further help :-)

Issue with update timing for a state in React Component (2 clicks needed instead of 1)

I’m working on a solo project using React and I’ve been stuck on something for the past 2 days…I'm starting and I'm very beginner so it's maybe something very basic, but I'm struggling...
To try to be concise and clear:
I have a searchBar component, that searches through a local database, and returns objects associated with the search keyword. Nothing complicated so far.
Each rendered object has a button that triggers a function onClick. The said function is defined in my App component and is as follow:
changeState(term){
let idToRender=[];
this.state.dealersDb.map(dealer=>{
if(term===dealer.id){
idToRender=[dealer];
}});
let recoToFind=idToRender[0].reco;
recoToFind.map(item=>{
Discogs.search(item).then(response=>{idToRender[0].recoInfo.push(response)})
})
this.setState({
objectToRender: idToRender
});
to explain the above code, what it does is that first, it identifies which object’s button has been clicked on, and send said object to a variable called idToRender. Then, it takes the reco state of that object, and store it to another variable called recoToFind. Then it calls the map() method on recoToFind, make an API request (the discogs() method) for each element of the recoToFind array and push() the results into the recoInfo state of idToRender. So by the end of the function, idToRender is supposed to look like this:
[{
…
…
recoInfo: [{1stAPI call result},{2ndAPI call result}…]
}],
The array contains 1 object having all the states of the object that was originally clicked on, plus a state recoInfo equal to an array made of the results of the several API calls.
Finally, it updates the component’s state objectToRender to idToRender.
And here my problem is, onClick, I do get all the states values of the clicked on object that get rendered on screen (as expected with how I coded the nested components), BUT, the values of the recoInfo are not displayed as expected (The component who’s supposed to render those values is nested in the component rendering the clicked on object other states values). However, they get displayed properly after a SECOND click on the button. So it seems my problem boils down to an state update timing trouble, but I’m puzzled, because this function is calling setState once and I know for a fact that the state is updated because when I click on the button, the clicked on Object details get displayed, but somehow only the recoInfo state seems to not be available yet, but only becomes available on a second click…
Would anyone have a way to solve this issue? :(
It somehow feels like my salvation lies in async/await, but I’m not sure I understand them correctly…
thanks very much in advance for any help!
Is this someting you want to do?
changeState(term) {
let idToRender=[];
this.state.dealersDb.map(dealer=>{
if(term===dealer.id){
idToRender=[dealer];
}});
let recoToFind=idToRender[0].reco;
recoToFind.map(item=>{
Discogs.search(item).then(response=>{
idToRender[0].recoInfo.push(response)
this.setState({
objectToRender: idToRender
});
})
})
}
you can call setState once async call is done and result received.

Next() is not being called on beforeRouteUpdate using the same component

I am using the same vue-component to display data that I'm fetching with axios. After clicking on a link the ajax-request is fetching new data.
But if the component is already loaded and the user clicks another link to load different data, the next()-method is not called.
Check out my codepen to see what I mean. There should be an alert showing. If you click a link for the first time, it does. If you switch to another link, it does not.
https://codepen.io/spqrinc/pen/YzXGGGL
From the docs:
Note that beforeRouteEnter is the only guard that supports passing a callback to next. For beforeRouteUpdate and beforeRouteLeave, this is already available, so passing a callback is unnecessary and therefore not supported
So the next() in beforeRouteUpdate can't take a callback because you already have access to the instance in this. Anything you would have done with vm in that callback can be done without it using this:
beforeRouteUpdate(to, from, next) {
alert("Reloaded");
// `this` works
next();
}

Page not refreshed when clicked delete button in angular

I have a page running at "http://localhost:4200/assignmentForAudit" and the UI looks like
When i click delete button then the data gets deleted but the page is not refreshed. I tried to put this.router.navigate(['/assignmentForAudit']); after delete operation but it is not refreshing the page.How can i achieve this refresh method so that the data gets removed?
method to delete in component.ts
onDelete(nas:any){
this.assignmentAudit.id=nas.assignmentAudit[0].id;
console.log(this.assignmentAudit.id);
if(window.confirm('Are sure you want to delete this item ?')){
this.assignmentAuditService.deleteGroupFromSelection(this.assignmentAudit.id)
.subscribe(
data => {
console.log(data);
},
error => console.log(error));
}
this.router.navigate(['/assignmentForAudit']);
}
assignment-audit.service.ts class method to call the api operation
deleteGroupFromSelection(id: number): Observable<any> {
return this.http.delete(`${this.baseUrl}/${id}`, { responseType: 'text' });
}
Delete operation is working fine but the problem is the page is not refreshing.
that's not recommended at all as a best practice when you using angular you can simple emit data list after every delete with that you update the data visually too but if you want such behavior.
First Case by reload the whole page you can do so after every delete
window.location.reload();
Second Case if you need just to reload the component you can work around that and achieve it by a hack (just to trick the component you navigate away and navigate again to it)
this.router.navigateByUrl('/DummyComponent', {skipLocationChange: true}).then(() => this.router.navigate(['Your actualComponent you want to reload']));
/DummyComponent could be a empty component you just gonna use it to trick the actual component you need to refresh/reload
Instead of trying to reload the page, call the http method which is used to populate the entries again on success of the delete http call.
this.assignmentAuditService.deleteGroupFromSelection(this.assignmentAudit.id)
.subscribe(
data => {
this.entries = this.http.get() // something like this. here this.entries refers to data that is used to populate html.
console.log(data);
},
error => console.log(error));
}
You can also use a BehaviorSubject to emit a value, listening to it, you can decide on calling this.entries = this.http.get() again.
You may need to use the 'onSameUrlNavigation' option in Angular routes.
RouterModule.forRoot(routes, {onSameUrlNavigation: ‘reload’})
Can your show how to binding array of object to template ? I thinks you just remove item from array then template it will update data too.
something like this:
this.nas.assignmentAudit = this.nas.assignmentAudit.filter(a => a.id !== this.assignmentAudit.id);

Extjs3 Component hierarchy - fetch all child components

I'm facing the following situation.
I have a formpanel, within this
formpanel I have another tabpanel in
which again form elements are placed
that are part of the formpanel.
Nothing spectacular. Basically a
formpanel with some "subforms" each
contained in a tab in a tabpanel.
Now I have added code to dis/enable each subform/tab when a user clicks a button in the toolbar. But in order for validation to skip all the formelements in a disabled tab I need to also disable each form field in the tabpanel individually so it skips validation upon submit.
That's when the trouble begins. Suppose in one of the tabs/subforms i have a fieldset with another nested fieldset.
How can i fetch all xtype:field elements contained in the tab/subform?
So basically what i'm asking is how can i fetch all components that are child components of the tab, whatever their depth in the component hierarchy is? When i have a method to collect all child components it's easy to just loop over them and disabled the ones that return true from Ext.isXType('field') ... but i have no idea how to gather all subcomponents when i have a reference to it's containing component.
This way:
var componentsArray = container.findByType('component');
Or even this
var componentsArray = container.findBy(function(c) {return true});
(should be even faster)
It should be noted however, than this will not return components within tbar, bbar, buttons properties of Ext.Panel descendands.
Edit Use findByType from Mchl's answer. I got mislead by an error in the Ext documentation.
You can use Ext.Container.prototype.cascade
cascade( Function fn, [Object scope], [Array args] ) : Ext.Container
Cascades down the component/container
heirarchy from this component (called
first), calling the specified function
with each component. The scope (this)
of function call will be the scope
provided or the current component. The
arguments to the function will be the
args provided or the current
component. If the function returns
false at any point, the cascade is
stopped on that branch.
I used it this way while testing this answer:
var children = [];
this.cascade(function(cmp) {
if (cmp.isXType('field')) {
children.push(cmp)
}
});
children contained 446 instances of field at all different levels.

Categories

Resources