Angular & Ionic State Change and history - javascript

I'm quite new to AngularJS as well as Ionic. Was wondering if anyone could help me figure out how to set a certain history before a state change?
Currently I have $state.go('app.lineup',{ 'lineupId': navURLID}); and I want to point the back button to 'app.lineups' which is the parent for the 'app.lineup' page.
Everything in my code works well however when I redirect a user to another state the back button returns me to the state I sent them from and not the parent state that I need to send them to?
Any help (even in the form of internet references wink) will be greatly appreciated :).
Thanks a mil!

one way to do it is to not make the parent state as abstract, let it actually resolve the route and in the parent states controller redirect to the desired child something like
$state.go('parent',{child:'childname'})
where child is not a param but a search param, and from inside the parents controller you do
$state.go('parent.'+search.child,{any: param})
that way you'll always go through the parent state first.
other solution would be to use replace or you can also use the replace property of the options object in the $state.go function
https://github.com/angular-ui/ui-router/wiki/Quick-Reference
it depends on your structure.

Related

Proper use of state in React

I am new to React and a bit struggling with state in React and how and where we need to use it. So far, I found out that "If modifying a piece of data does not visually change the component, that data shouldn’t go into state". So, state is all about re-rendering the UI(I hope I am correct). So, the question I want to ask is Is it true that we use state only for re-rendering the UI only?, nothing else and nothing more?
You can use state in your class components. State is like private data of your component that may change by action made by user.
State is immutable. This means you can not change state directly in following way this.state.someVal = "smth". The only way to change state is using this.setState() method.
When you change state value React automatically re-renders your component without refreshing the page. In other words React.js reacts to your changes
State is an object that is directly tied to rendering the component. The reason why you can't change State directly with say this.state.foo='bar' is that React would have no way of knowing that it needed to re-render the component if you did that. Thus there is a setState method to change the state, which under the hood calls the render function of your component.
Therefore, if you have some data that has nothing to do with rendering the component, you don't want to put it into state, as setting its value will cause unnecessary renders to occur. If you're using class components, you can just put that data on the class directly: this.foo='bar'.
Basically yes! Two examples might be: A - holding a list of items (shopping list, or todo items) that are rendered directly to the UI, that are subject to change as the user adds and removes items. B - a value that determines whether or not you want something to show up on your UI, for example, you might have a state value called 'showNavbar' that is either true or false, depending on whether you want the user to see a navigation bar.
I hope that helps make sense of it in a basic way :)
We use the state for rendering the UI.
Also, I think the State allows React components to change their output over time in response to user actions, network responses, and anything else, without violating this rule.
For this, We use the 'setState' method.
setState() is the only legitimate way to update state after the initial state setup

Angular UI Router - Fire resolve function of parent state from child state

Is there a way to fire a resolve function of a parent state again, after i transitioned from a child state back to its parent state?
Think of a service which holds an array of objects.
For "security" reasons, my service only gives out copies of the objects it's holding, to prevent direct manipulation from the controllers.
The array of objects is retrieved from my backend and saved in the service, the first time i go to the parent state and is resolved to this parent view.
If i transition to a child state, my service hands out one object of this array to manipulate it. After manipulation, changes get saved by my service and the original array gets updated with the new manipulated object.
After this, i transition back to my parent state, but because of ui-routers nature, the resolve function isn't fired again. My parent state displays the old array instead of the updated one.
But of course, i want the new data loaded. I dont want to work with broadcasting events, or manually retrieving stuff from my controller (in this case). I can't use the reload param of ui-router because i need it to work on window.history.back() as well.
Any ideas how to solve this? I could get it working the way i want by not using nested states (no child states), but actually, thats not a real option.
So the only option i see at the moment, is not to work with copies in this case, instead just use references.

Iron Router hook on a route before actually changing the template

i am trying to show the user a payment popup as soon as he clicks on a payed object.
But after he pays he should directly enter the content he clicked on.
Therefore i think its a good solution to solve this with the router, because i want every link on the page that redirects to this content to show this popup.
My problem is i want to show the popup before redirecting the user.
So i tryed the onBeforeAction hook and stuff but everything working with the iron router seems to only hook in after the URL of the browser changed and the current template was unloaded.
Do you have an idea how to get this kind of behavior?
Cheers
Based on this answer, here is how you can hook the router using Router.onStop():
// onStop hook is executed whenever we LEAVE a route
Router.onStop(function(){
//check if the current route is the page from where you need to show your
//popup and show it based on, for instance, a session variable containing
//the previously clicked content id.
});
It's a common use case that I don't think is directly achievable within the iron router framework at present (although I would be delighted to be corrected!). As you've discovered, onBeforeAction is run before the page has rendered but after the new route has been run, so the old page has already disappeared.
Effectively, you're looking to queue the running of a new route until a certain action has been completed. The use case for which I've experienced this requirement is page transitions, for which the best solution appears to be to do completely the opposite of what you propose: i.e. to add the logic to an event attached to the link, and only redirect to the new route once that logic has been satisfactorily completed (i.e. the popup has been closed in your case).
I agree that doing something in the router would be a sensible way to approach this, but I'm not sure it's possible in iron router as things stand. Note that this has already been raised though!
Will this workshop?
'unload - runs just once when you leave the route for a new route.'
From
https://github.com/EventedMind/iron-router/blob/devel/DOCS.md#unload-hook

How to handle action "sent" by Ember component in wrapping view or view's controller?

I'm learning Ember and got into an issue I can't seem to find a solution for: I got a view that contains a component and that component handles a button click. I want to "send" that action to the wrapping view and handle it there if possible. That'd be the preferred way. If not possible, then handling it in the view's controller is OK too.
But I can't seem to catch that action anywhere, not even in the current route or the route's controller. I don't know where the action is being sent to, I thought I'd be able to handle it in the current context's controller but it seems that is not the case.
Here is a fiddle that illustrates my issue:
http://emberjs.jsbin.com/juzif/1/edit
I get the action inside the component, but the sendAction doesn't seem to do much.
What am I doing wrong?
I still haven't seen any solution of how to target the view from the component, but for the controller->route etc you need only define where the action need be sent to from the component (this is super helpful when you have the component in a particular controller/routes scope and you want it to be handled differently based on the interaction of each component, or if you want to ignore it, which is currently what's happening for you)
{{foo-bar blah=view.foo dataUpdated='dataUpdated'}}
or better said
{{foo-bar blah=view.foo internalAction='externalAction'}}
http://emberjs.jsbin.com/misiyaki/1/edit
Additional answer responding to "I still haven't seen any solution of how to target the view from the component":
The magic word here is targetObject:
{{foo-bar action='actionName' targetObject=view}}
This also works in each loops targeting an itemController like so:
{{#echo posts itemController="post" as |p|}}
{{foo-bar action='actionName' targetObject=p }}
{{/each}}
taken from #jasonmit´s answer here:
How to send an action from a Ember component to a View that wraps it?

Correct way to do this in emberjs

So should the click action goto a method on the router say 'showPropertyPanel' and that puts the router in a showProperties state on this page show route?
Then setup the properties outlet.
Is this correct?
Problem is I don’t want the route to change from /pages/1234 to /pages/1234/showproperties
Is this the correct way to do this now all actions through the router to change state? Can you have states with and without routes mixed in together?
Before I would just fire an event on the PageView to create the Properties Panel and show it etc.
Please can someone give me some help on this as I am sure I am not the only on struggling with this at the moment?
Your event handler, on the state, does not have to go to a new state to show the panel. It can, but it doesn't have to. It's sort of an architectural decision on how to handle such things. If complicated things can happen when the panel is up, you might want a new state, to handle all the events that can originate from the Panel.
On the other hand, you can do what you were doing before, but do it in the router instead of directly on the view.
With respect to the route issue, can't you just do
route: "/",
on the panel state to keep it the same as it was before?

Categories

Resources