What is the "key" which changes on every route change with connected-react-router? - react-router-v4

When an action for navigating to a route is triggered, an action triggers a new state where the router.location.pathname changes according to the browser's history.
Another property changes as well: router.location.key, to a new random string.
Even when the pathname itself doesn't change (clicking on a link to a page from the page itself), the key still updates.
What's the purpose of the key property? In which situations would I want my own state to have a randomly generated key which updates on very action dispatch? Why is it not a number which simply increments?

connected-react-router simply stores the location object from react-router which in turn creates the location object using the history package. In the readme of history the key property is described:
Locations may also have the following properties:
location.key - A unique string representing this location (supported in
createBrowserHistory and createMemoryHistory)
It is used internally (e.g. in https://github.com/ReactTraining/history/blob/master/modules/createBrowserHistory.js to find locations in the current history stack) and should be treated as an implementation detail of react-router. I suspect a random key instead of a incrementing sequence number was simply the easiest way to implement unique ids (you don't have to store the current sequence number).

This causes unnecessary rerender of the current route, when visited once again, because props change. One way to fix that would be to use React.memo, and comparing the location.path which stays the same. But then you will have to be careful if your component receives other props, so to include them in the comparison.

From the React Router Docs
Each location gets a unique key. This is useful for advanced cases
like location-based scroll management, client side data caching, and
more. Because each new location gets a unique key, you can build
abstractions that store information in a plain object, new Map(), or
even locationStorage.

Related

HTTP verb for appending to a resource object?

I am trying build an api which conforms to the json:api spec.
My api has three resources /task, /item and /result. A task has the fields name, description and state. A item has the fields itemName. A count is kept server-site for the item and the count is returned when a user retrieves the item with a GET request. The count is incremented server-side when the item is updated. There is a one-to-many relationship between task and item. In a sense an item is appended to a task. When the tasks state changes a script runs server-side to do some processing on the associated items. Once the script finishes the output is available in the result resource.
Per the spec, I am using the POST verb to create a task and the PATCH to update a task. I just want one endpoint which handles both the create /update (appending) of an item. But, I'm not sure which verb to use? Can I use PATCH to update the item but also create an item if it doesn't exist?
I also thought that perhaps I should be using the PUT verb. But, my understanding here is that this verb is used to simply replace a resource rather than update it. I don't think this is right for my user-case as an items count is incremented when updated, so replacing it is not what I want todo. But, the count is handled server-side so a user doesn't have the option of "replacing" the count anyway.
my understanding here is that this verb is used to simply replace a resource rather than update it.
This is a common understanding - wrong, but common.
The IANA registry documents the authoritative reference for the semantics of http methods. Most of the common ones are defined by RFC 7231; PATCH is defined by RFC 5789.
PUT is an appropriate choice when the message body is a complete representation of what you want the resource to be. It may be easier to think about "saving a file"; PUT describes what the client expects the document to look like when it has been saved.
It's appropriate to use PUT for either updating a document or creating one, provided that the client knows the identifier for the document (just in the same way that we can use save to create a file, or replace a file, but we need to know the file name).
If you read the text of the specification, you'll see that - while the semantics of the request are to save the new representation "as-is", the server isn't required to do that -- the server, after all, is in control of its own documents -- so there is room to cover read only fields, or fields that should be updated by the server only. You need to have a little bit of care with the response headers to avoid implying that you saved the representation as is, but other than that you should be fine.

Self contained component data model vs master root data model

I looking for feedback regarding how I am implementing Vue components.
I have a Vue instance that contains a list of orders and a reference to the current order. Let’s call this root instance "orders".
When the current order is set (based on clicking on one of the orders in the list), I create a new component inside "orders" called "current-order". "current-order" has a property that the parent passes it called "order_id", this property is used within "current-order" to recall the data for the order and present an editable form.
Within "current-order", besides the meta-data associated with the order (customer, etc), I have a third component to contain a group of items, let’s call this final instance "item-group".
Here is the general layout of how these instances would look:
orders
current-order
item-group
item-group
item-group
"orders" only saves a list of the orders; it does not save any order data.
"current-order" saves the meta-data associated with the order, as well as the item data.
Discussing this model with a co-worker, he explained to me that this is not the best-practice way to implement this. He felt that the proper way to implement this would be to save all of the data for all of the components on the root instance "orders", versus the way I implemented it - data saved at each level.
The model he explained seems less maintainable to me. "current-order" may be used on other pages of our application, so if I maintained its data in the root instance, I would have to do that in all of the root instances that I attach it to.
With the way I have implemented it, all you have to pass the component is an order_id, and it will fill itself with data.
He continued to explain to me that saving data on the component like I am doing can be reset by re-renders of the instance, which I didn't quite understand.
Both the way I implemented, and the way he described would work, but I'm trying to find out what the best-practice approach would be for maintainability.
Note: This is not a large SPA, and I don’t think Vuex would suite what we are trying to achieve right now.
Any feedback would be appreciated.
It all depends on what your child-components are responsible for. If a child is extending the functionality of your parent component then the state should always be maintained in your parent component. For example in a CRUD based situation instead of creating separate components for create and update you can write only one and maintain its state (updated/created) in your parent component.
If in your current-order you are not updating anything related to the order then no need to maintain its state in your order i.e. if meta-data can be treated as a separate entity of your order no need to maintain it in the parent. But in case both order and its meta is one single entity, you should maintain its state in your parent.

jQuery DataTables: How can I explicitly set the table instance name / table ID to use with state saving?

Background:
I'm using DataTables in conjunction with a JS library called "Turbolinks", which basically turns your application into a Single Page Application (SPA) without all the overhead of using a true client-side framework. It is extremely useful for Ruby on Rails application performance.
There's a couple of headaches it introduces though - one is compatibility with DataTables. I've got it working pretty well by basically destroying any DataTable on a Turbolinks navigation, and then re-initializing it on turbolinks page load again. This method works well and seems to be the all-around accepted answer as to the best practice to get DataTables to work with Turbolinks.
Question:
On of the last features / finishing touches I'm trying to add to some of my applications is DataTable state saving. The issue I'm facing is that every time a table is destroyed/re-initialized on a page navigation, the...I'm actually not quite sure what to call it, but it looks like from inspecting the settings object on the stateSaveCallback - it looks like its the sInstance and/or the sTableId:
DataTables_Table_0
Then the localStorage key gets set as:
DataTables_DataTables_Table_0_/current_path: "{data: data}"
where current_path is whatever path/page you're on.
Then when it get re-initialized upon returning to the page, it gets set as DataTables_Table_1, and so on and so forth - so the state never gets correctly loaded.
Is there a way to override that ID (or some way to set the name of it in the stateSaveCallback / stateLoadCallback) so that it doesn't increase the last '0', '1', etc at the end of it? That way when the table is re-initialized, it will pull the saved state from just DataTables_Table/current_path?
The answer is to simply give the table an ID! Then DataTables won't assign it its own ID with the incrementing number and the saveState option just works.
Also, the destroy/re-init actually causes the server to get hit twice in the case of an AJAX table.
The better way to do it is to disable the turbolinks cache for any index pages with datatables. If not, you'll end up doing two requests to the server when only one is needed.

FactoryImpl to set atts via props for bound inputs

First, thanks for any advice. I am new to all of this and apologize for any obvious blunders.
Second, the question:
In an interface for entering clients that often possess a number of roles, it seemed efficient to create a set of inputs which possessed both visual characteristics and associated data binding based simply on the inputs name.
For example, inquirerfirstname would be any caller or emailer who contacted our company.
The name would dictate a label, placeholder, and the location in firebase where the data would be stored.
The single name could be used--I thought--with a relational table (state machine or series of nested ifs) to define the properties of the input and change its outward appearance and inner bindings through property manipulation.
I created a set of nested iffs, and console logged the property changes in the inputs, but their representation in the host element (a collection of inputs that generated messages to clients as well as messages to sales staff) remained unaffected.
I attempted using the ready callback. I forced the state change with a button.
I was unable to use the var name = new MyInput( name). I believe using this method would be most effective but am unsure how to "stamp" the JavaScript into a heavyweight stamped parent element.
An example of a more complicated and dynamic use of a constructor and a factory implementation that can read database (J-son) objects and respond to generate HTML elements would be awesome.
In vanilla a for each would seem to do the trick but definitions and structure as well as binding would not be organic--read it might be easier just to HTML stamp the inputs in polymer by hand.
I would be really greatful for any help. I have looked for a week and failed to find one example that took data binding, physical appearance, attribute swapping, property binding and object reading into account.
I guess it's a lot, but each piece independently (save the use of the constructor) I think I get.
Thanks again.
Jason
Ps: I am aware that the stamping of the element seems to preclude dynamic property attribute and binding assignments. I was hoping a compute attribute mixed with a factoryimpl would be an option (With a nice example).

Ember: global mapping from typekey to model name coming and going

The server API changed from using type keys of "foo" to "bar". My Ember app uses foo everywhere, and I don't want to change them all to bar. I see I can use typeForRoot to map root-level hash keys to a model name, but that appears only to apply to downloading. When I do a save on my Foo model, I want the PUT to be generated with a hash key of boo as well. Is there any simple way to completely map type keys to models, both coming and going?
The answer I posted on another stack overflow question might help you..
Basically the function you need to look at is the stores _normalizeTypeKey.
You can override the stores _normalizeTypeKey then alter the camelCase behaviour to become what you want (e.g. dasherized or just fix this one case).
You can also override the serialisers typeForRoot when going the other way - this lets you tell ember what the model key is (e.g. tellMeAStory) for a particular key in your data (e.g. tell_me_a_story).
It appears there is work underway to make everything work like the container does (which is dasherized)