I'm dealing with a hand full of javascript objects that i get from an external api-library. I want to store the incoming objects in my react application using redux.
These objects are es2015 classes that also come with two handy methods called fromJSON and toJSON. As i want my redux store to be serializable (as it should be) i need a way to translate them to plain objects (toJSON does that by giving me back a dict). In my application i need to use these Objects as they come from the API since i need the methods attached to them and the api-client also wants these specific objects.
Is this a common need as i can't find much about this online or am i totally going the wrong path? How would i implement such a transformation? I'm currently thinking about attaching the es2015 classes to my action and call toJSON in my reducers. I could then create specific selectors that catch the json from redux and convert them back to the classes using the fromJSON functionality (would i have to memoize them?). These selectors could then be used in mapStateToProps to map then finally to a prop.
Let me know what you think about this and how/if i could improve this process.
Redux says the state SHOULD be serializable. It should be so, because at some point you might need to store the state locally (via some form of localstorage). But this does not mean the state has to consist of plain objects.
For example, lot of projects use Immutable.js objects for their state. There is an overhead serializing Immutable.js objects. But it can be done using transit-immutable-js.
From what I understand this principal is similar to your question.
What I understand from your question is that (whatever you mean by ES2015 classes) are deserializable/serilizable by fromJSON and toJSON methods, which is all you need.
Thus you can use your "API" objects in state and serialize it only when you need to store it locally.
Related
in reading Mobx's documentation for its recommended best practices for defining data stores (see https://mobx.js.org/defining-data-stores.html), I see that the domain objects are stored in an array (in the example code "Example domain store, the TODOStore class contains a field "todos" which is an array). In that same class, functions like updateTodoFromServer and removeTodo do a linear scan matching by id by calling .find() or indexOf(). (The removeTodo function also has to call splice too!)
Normally, in a not-mobx context, based on this usage I would say that the todos field should actually be a map that allows you to look it up or delete it by "id" in constant time (or at least logarithmic time) rather than linear time.
BTW, in my own code, the number of items in the mobx store could theoretically be very large (if all possible items were pulled in)
Is there a reason the mobx documentation examples use an array here?
What if I used a map/ObservableMap instead? Is that better? Neutral? Not recommended?
If maps are indeed better... does a normal map or an ObservableMap make more sense here?
Thanks in advance for helping me understand mobx better.
I tried reading mobx documentation and asking the question in a search engine and reading multiple search results, but I didn't find an explanation to my question yet.
I’m working on a web application users add objects to a database. The structure of these objects is fixed, but some of them have a data property that contains a map of strings, for example { title: "Test", description: "Description" }. Both the keys and the values in this map are user-defined, so theoretically users can define keys like constructor, __proto__ and __ob__.
I want to store the database objects in the data of a Vue 2 component, so they will be made reactive. I'm having trouble to decide which data type I should use for the data property. The following options come to my mind:
Usually I would use a null-prototype object for the data property. So create it using Object.create(null). This would make sure that keys like constructor and __proto__ would work without problems, but there would be problems with the __ob__ property added by Vue. I’m not sure if deleting that property would cause any trouble for Vue, but I guess it will just add the property again on the next occasion.
The proper way to do it would be to use ES6 maps. But as far as I understand, Vue 2 doesn’t support these yet, so they won’t be reactive.
I could use or write a custom class that has an interface similar to ES6 maps but internally stores the data in an array or something else that Vue’s reactivity system supports. There seem to be plenty of ES6 map polyfills out there, but I’m not sure which ones of them would work flawlessly with Vue’s reactivity system.
What would be the best way to store such a map of values with user-defined keys in a reactive Vue 2 object?
In the end I wrote my own class that has an interface similar to ES6 maps, so that migrating to ES6 maps will be straightforward when I migrate to Vue 3 one day.
In my class, I'm storing the map entries in an array of [string, string] tuples. I'm using an array because Vue 2 has good reactivity support for arrays, and I'm using tuples because then the array's iterator has the same data type as an ES6 map iterator. You can find the source code of my class here.
Other solutions to the problem were suggested in the comments:
Use a prefix for the property keys
Use the Vue 3 composition API in Vue 2 using a plugin
Should derived data be the responsibility of the NGRX store through selectors or should it be defined on the component that will use it? For example, let's say you have an object with startTime, itemsCompleted, and itemsRemaining. A utility function calculates some other properties such as expectedLate, expectedOverage, etc. Should that take place inside a selector or locally on the component? Does it matter?
Personally, I like to use selectors for derived data. A component just retrieves data from the store and displays it.
This imho makes selectors and components easier to test.
Following this convention it's also easier for devs to find the information they are looking for.
Also, you have one single source of truth. For example, if a user logs out you just have to update the user instead of updating the user and setting a isLoggedIn flag to false.
I'm working on a project that brings in a ton of data from one endpoint into a a single reducer. I'd like to convert that data in ES6 Classes, so I can give them helper method, provide relations between the data, and not have to work with plain javascript objects all the time. Also, to get relations between the data, I'm having to do n-squared computations and that's slowing down the frontend.
Here are the options I'm seeing:
1) Create a selector that connects with the redux store. This selector could get the data from the reducer and convert it into multiple ES6 classes that I've defined. If the reducer gets new data that is different, then the selector will recreate the ES6 class instantiations.
2) https://github.com/tommikaikkonen/redux-orm
This seems fantastic as well.
3) Create multiple selectors on the data set to that will compute a specified relation in the data set, so I can just call that selector each time I want to get a relation that would otherwise be an n-squared computation to get.
My question is which route of the three should I take? Is there an alternative besides these 3? Or do people just work with javascript objects mostly on the frontend and not deal with ES6 classes.
Update:
Two months later, and I'm still using Redux-ORM in production and it is fantastic! Highly recommend.
It's certainly entirely possible to do all that handling with "plain" functions and selectors. There's info on normalization in the Redux FAQ, and I have some articles on selectors and normalization as part of my React/Redux links list.
That said, I am a huge proponent of Redux-ORM. It's a fantastic tool for helping manage normalized/relational data in your Redux store. I use it for normalizing nested data, querying data, and updating that data immutably.
My Practical Redux blog post series includes two articles talking about Redux-ORM specifically: Redux-ORM Basics and Redux-ORM Concepts and Techniques. The latest post, Practical Redux Part 5: Loading and Displaying Data, shows Redux-ORM in action as well.
The author of Redux-ORM, Tommi Kaikkonen, actually just put up a beta of a major update to Redux-ORM that improves the API and behavior, which I'm looking forward to playing with.
I definitely recommend it!
I'm writing a React component that I intend to make public, and I'd like to have it play nice either with JS arrays/objects, or immutable.js equivalents (Map/List).
What's the best way to identify an Immutable.js Map or List? I don't want to simply use Array.isArray, because I do want to enforce that it is either an Array or a List, for example.
I could just check for some of the Immutable.js properties, like _origin or __ownerID, but I don't want to depend on internal APIs that are subject to change in minor versions.
I would very much recommend the suggestions given by #robg and #joseph-the-dreamer. However, just for the sake of answering your exact need, for every Immutable.Type there is a Immutable.Type.isType() static function which you can use to determine if a given object is of that type.
E.g. Map docs -
var im = require("immutable");
if (im.Map.isMap(someObjectWhichMayBeMap)){
...
}