I got an array of objects, in similar structure to this:
arr = [ { key1: 'test', key2: 'text' } ]
This array and the object keys and values in it my be change,
then possibly go back to original with user interactions on the page.
I got an unsaved changes feature to develop, where when I leave the component I wanna see if there were any changes (including deeply nested ones) in this array.
Is there a way to detect this change in angular?
I suppose you could use a service to store the original values. You could compare the current value to the original to see if there is a difference, and be able to reset it like you wanted.
when I leave the component I wanna see if there were any changes (including deeply nested ones)
The "when I leave" part suggests using the ngOnDestroy hook. Now, dependent on your use case, you can emit the current value to component's output, or feed it to a shared service (you didn't share much about your application's architecture).
Related
I am new to react and I'd like to ask a high-level question. Any directional advice will be welcome.
So, here is what I did in vanilla JS. I defined an empty variable first, and put the results of a DB query there. Then created buttons I did filter operations to only populate the items that satisfied the filter criteria. So, to illustrate, it looks like this:
const things = [
{continent: Asia, country: Korea},
{continent: Europe, country: France},
{continent: Africa, country: Egypt},
.....
];
const filter (continent) = > {
//Logic to filter based on continent criteria and return the countries
};
This was possible in vanilla JS, because I could set aside the array variable in the script document and the functions would easily reference it.
The question is: how do I do something similar in react? i.e. what would be an equivalent way to store a variable that lasts as long as the page is active, so that I can do filter operations on them? Obviously, setting aside a variable outside of the component doesn't work after the page is rendered. Where should I look to resolve this?
Any advice will be appreciated. Thanks!
For this you can either do one of three things
Pass an array defined at the top level between children and
parents (can work for simple pages)
Use the React Context Api
https://reactjs.org/docs/context.html
Look into a state management library like Redux (most recommended if your application is complex) -
https://redux.js.org/introduction/getting-started/
If I understand correctly, you want to write data on a page server-side, and then load it into a React component client-side. I would try writing the data into a hidden element, probably in csv format, with an "id". Then, when your App component loads, use document.getElementById to retrieve the data. Pass that into your component tree, and filter away.
Sorry, I'm not able to test this out at the moment. There may be some gotchas with this approach, but if you don't want to fetch the data client-side, hopefully something like this will work.
I have one observable array in my store that is deeply nested. Lets called the property people (which contains elements of class Person). Now the Person class has a property products which is an array of Product, a class which also has nesting through ShippingInformation and so on. When the app is loaded I get the people array with all nested data. Now upon any data update I receive the updated peoples array again from the server. A lot of the times the elements in the people array are the same, the only change being some ShippingInformation.
Now how should I update the existing observable array people? I do not want to reassign it because often times the direct Person elements are the same. It is only some nested information on one Person that has changed. Is there a way that I can sync the two arrays without changing the ref on the array with a reassign so that I avoid major rerenders in react? Can mobx help me here or are there any other lib I can use to help me update without triggering unnecessary rerenders? If not, are these rerenders that bad, performance wise, I guess react must go through the diffing process at least
While I was messing with routing in Angular, I tried using an in memory database to fetch the heroes.
The original StackBlitz is https://stackblitz.com/angular/yoerxnmrbod
If you go to the heroes tab, click on a hero, and change his name, the change is reflected in the list.
I changed how the data is backed to be the angular in memory database.
https://stackblitz.com/edit/angular-ke7pxn-vxp9hi?file=src/app/app.module.ts
If you follow the same workflow as the above, the name change in the details component isn't reflected in the list. What am I missing to get the same functionality?
It seems that the reason is when you set HEROES as const in hero.service and then pass a separate hero and change his name, the name is changed in your HEROES array element (because it's an array of objects, and even if it is const, it's elements and their properties can be changed). And in the second realization, you always get a new instance of heroes array. If you want to save some changes to it, you should store it in your service and use like a simple array (without async pipe) and not receive it from your mock-backend each time.
I'm trying to create a very basic key-based translation system since our system doesn't have to be as expansive as something like vuei18n. I'm simply loading a json with a key and each key has four translations. About a hundred items in total. Now; I'm using a seperate Translator window component that I link to Vue like this;
Vue.prototype.translate = function(key){
window.addEventListener('switchedLanguage', function(event) {
console.log(event.detail);
return window.translator.getTranslation(key);
});
return window.translator.getTranslation(key);
}
and in order to render them in the templates I do the following:
{{ translate('key') }}
I understand that connecting scripts like a translator directly to the window isn't the best of practices, but is what's working in the application right now.
The thinking behind it is that when the language is changed within the translator, it will try to get back the key. While this technically works, in the application I am not seeing the keys get re-rendered to the different language. I've been deep down the rabbit hole now and don't seem to get a clear answer why except for the fact that it's not bound to the data model. But for some of the components, they can have up to fifteen keys or more depending on input. It's not feasible to store all the keys in the data model of each component since that will, in my view, unnecessarily clutter the data model.
So, what I've tried so far is the following:
Use a filter with the key as an input (this results in Vue freaking the hell out because it can't resolve the filter since it isn't able to find the translator through Window.translator)
Reload the entire window (while working, very ugly solution since it takes the user back to the main screen)
I want something like document.referrer. But since I'm building a single page app, with backbone and pushstate, the value is "".
How can I get something like history.prevState().url.
EDIT: I do not need the event. I want to access info of the previous state anytime/anywhere I want.
Perhaps you could simply store the last state in the new state object.
history.pushState({
lastState: 'some state'
}, '', 'newpage.html');
console.log(history.state.lastState); //some state
If you are building a single-page application, even if there are no standardization on how the state transition is initiated you could probably manage to intercept all of them by listening to the popstate and the onhashchange events.
You could then just push every states encountered in an array and store a serialized version of it in the localStorage. That would allow you retrieving any previous states. However, this collection will grow so you would have to make sure that you control it's size. You could also simply keep the last state instead of all of them.
However, it would definitely be better to establish a standard across modules. Not only it would make accessing the previous state easier, but it would also be easier to maintain and more flexible in terms of future changes.