mschipperheyn / normalizr-immutable Goto Github PK
View Code? Open in Web Editor NEWLicense: Other
License: Other
projects.toString() // from "state.projects", Map instance
and many other functions throw this error (eg ownProps.project.tasks.includes(taskId)
there)
I saw you redefined many functions from immutable
, maybe this is the source
const InvoiceRecord = Immutable.Record({
IsFetching : false,
FetchDetailsError : null,
ClientID : null,
ClientName : "",
Created : "",
Date : "",
DelegateID : null,
ID : null,
InverseTax : null,
Number : null,
Paid : null,
Serial : "",
Total : null,
TotalVat : null,
VatAtCashing : null,
});
export class Invoice extends InvoiceRecord {
hasFetchingError () {
return this.FetchDetailsError !== null;
}
isFetching () {
return this.IsFetching === true;
}
shouldFetchDetails () {
return this.Cashing === null;
}
}
based on official Record Class documentation
We have the following deep merge scenario.
const initialstate = new Map({
isLoading: false,
dteUpdate: Date.now(),
entities: null,
result: [],
visibleResults: [],
totalVisible: 12,
resultCount: 0,
currentMessage: null
});
const normalized = normalizeJson(json.result.items, arrayOf(messageSchema), getState);
dispatch({
type: types.LOAD_MESSAGES,
payload: {
entities: normalized.entities,
result: normalized.result,
resultCount: json.result.items.length
}});
export function loadMessages(state, action){
return state
.set('isLoading', false )
.set('dteUpdate', Date.now())
.set('entities', action.payload.entities)
.set('result',action.payload.result)
.set('visibleResults',action.payload.result)
.set('resultCount',action.payload.resultCount)
}
const normalized = normalizeJson(msg, arrayOf(messageSchema),getState);
dispatch({
type: types.SEND_MESSAGE,
payload: {
entities:normalized.entities,
result:normalized.result,
}
});
//-----
export function sendMessage(state, action){
return state
.set('isLoading', false )
.mergeDeepIn(['entities','messages'], action.payload.entities.messages)
.updateIn(['result'], (v) => v.push(action.payload.result))
.updateIn(['visibleResults'], (v) => v.push(action.payload.result))
.updateIn(['resultCount'], (v) => v+1)
};
The data structure get merged but some mutations are made wrong in the deep level
As a normalizr-immutable user, I would like to merge deeply and be able to use all Map functions as well.
Hey I'm having some trouble merge entities together, I might be doing something wrong, so wanted to get some feedback here first.
My view loads an initial list with basic information, the view is paginated, when I scroll down, we fetch more items from the backend, which should merge the data to the current state. When I click on an individual item, I will show the basic information, fetch more data in the background for this specific item and merge it to the entities.
I'm having issue with the merge, when I try to mergeDeep I get collection.update
error.
Here's a sample of my code below:
// schema.js
import { arrayOf, Schema, } from 'normalizr-immutable';
import { Map, Record } from 'immutable';
const reducerKey: string = 'myReducer';
/* records */
const Item: Record = new Record({
users: new Map(),
});
const User: Record = new Record({
id: undefined,
fullName: undefined,
});
/* schemas */
export const itemSchema: Schema = new Schema('items', Item, { reducerKey });
export const arrayOfItems: Array = arrayOf(itemSchema);
const userSchema: Schema = new Schema('users', User, { reducerKey });
itemSchema.define({
users: arrayOf(userSchema),
});
// actions.js
import { arrayOf, normalize } from 'normalizr-immutable';
export function fetchItem() {
return (dispatch: Function, getState: Function) => {
dispatch({ type: FETCH_ITEM_REQUESTED })
Api.getItems()
.then(payload => {
dispatch({
type: FETCH_ITEM_SUCCEEDED,
payload: normalize(payload.item, itemSchema, {
getState,
useMapsForEntityObjects: true,
useProxyForResults: true
})
});
})
.catch(err => dispatch({ type: FETCH_ITEM_FAILED, error: true, payload: err }));
};
}
export function fetchItems() {
return (dispatch: Function, getState: Function) => {
dispatch({ type: FETCH_ITEMS_REQUESTED })
Api.getItems()
.then(payload => {
dispatch({
type: FETCH_ITEMS_SUCCEEDED,
payload: normalize(payload.items, arrayOfItems, {
getState,
useMapsForEntityObjects: true,
useProxyForResults: true
})
});
})
.catch(err => dispatch({ type: FETCH_ITEMS_FAILED, error: true, payload: err }));
};
}
// reducer.js
import { NormalizedRecord } from 'normalizr-immutable';
const initialState: NormalizedRecord = new NormalizedRecord({});
export default function reducer(state: Object = initialState, action: Object) {
const { payload, type } = action;
switch (type) {
case FETCH_ITEM: // Load just one item
return state.mergeDeepIn(['entities'], payload.get('entities'));
case PAGINATE: // On paginate add more
return state.mergeDeep(payload);
case FETCH_ITEMS_SUCCEEDED: // Initial fetch
return state.merge(payload);
default:
return state;
}
In my project I persist the state using redux-persist-transform-immutable (which uses transit-immutable-js) making it possible to store & restore Records to and from local storage. This works well for most of my state except the entities.
The problem is that when using normalizr-immutable the entities are Records containing a list of Records, which is stored/restored by redux-persist as a Map because the persistor doesn't know the structure of the entities Records.
This is how the entities reducer is persisted:
You can see the structure a bit: iR identifies a Record, iM identified a Map:
entities is a Record (I defined it like that in the persistor), but users is a Map containing UserRecords.
Before persisting it looks like this:
So after a restore, I can't access my objects anymore using number IDs so I have to convert my IDs to Strings.
I hope I'm making a bit of sense?
Do you see a way around this or should I just resort to referencing entities using a Map?
You can use the proxy to get an object reference from a provided state so, you don't have to manually retrieve the id from the state. This is great because it allows you to use you normalized object structures as if they had never been normalized.
However, in some cases you want to be able to turn this off. For instance, when you merge data or when you serialize data for storage.
It would be ideal if you could late bind the state to the proxy so it will only process the proxies if the state is bound and otherwise, it will just return the id. The challenging thing is that this is a deeply nested structure.
Any ideas?
We used create-react-app to create react project
when I tried to include library:
import {normalize, arrayOf} from 'normalizr-immutable'
,
the web page failed to be rendered by Googlebot:
it works after code line removed
related packages:
"babel-polyfill": "^6.26.0",
"normalizr-immutable": "0.0.3",
"react": "^15.6.2",
"react-dom": "^15.6.2",
"immutable": "^3.8.2",
"react-redux": "^5.0.6",
"redux": "^3.6.0",
"redux-thunk": "^2.1.0",
Any ideas on how to use proxies if the stores come over prepopulated from the server? Seems like you'd have to de-normalize and normalizr-immutable?
Currently, we use harmony-reflect as a shim for harmony-proxies. However, you don't want this included in situations where the target environment already has full support for proxies. This should be more flexible.
Any thoughts on allowing reducerKey to be defined on a per schema basis to support proxying across reducers?
NormalizedRecord cannot be merged with previous entities, records are replaced and not merged together as one would expect. Using mergeDeep (which would handle list concatenation) throws an error as entities is a Record and not a List.
import { Schema, arrayOf, normalize, NormalizedRecord } from 'normalizr-immutable';
import { Record } from 'immutable';
const record = Record({ id: null, name: null });
const schema = new Schema('articles', { record });
const results = normalize([
{ id: 1, name: 'One' },
{ id: 2, name: 'Two' },
{ id: 3, name: 'Three' }
], arrayOf(schema));
const more = normalize([
{ id: 4, name: 'Foo' },
{ id: 5, name: 'Bar' },
{ id: 6, name: 'Baz' }
], arrayOf(schema));
let state = NormalizedRecord();
console.log(state.entities === null);
state = state.merge(results);
console.log(state.entities.articles.size); // 3
// Uncaught Error: Cannot set unknown key "4" on Record
// state = state.mergeDeep(more);
state = state.merge(more);
console.log(state.entities.articles.size); // 3 <-- Expected a size of 6
After a normal npm install
I was unable to import anything from the library.
I am unfamiliar with publishing libraries like this so I'm probably wrong, but could this be due to
no index.js
being present for this library? I see no index.js
in the src
folder.
Hi, thanks for the great library. Currently the latest release on npm is still 0.0.3 which requires native Proxy support on browsers. I've tried the 0.0.4 pre-release, it already made dependency on Proxy an option.
Normally I would just be fine making my dependencies to this git repo, however this time it dosen't work if I do npm install against this git repo, as the npm run build fails silently.(on windows 10). So I had to grab the source code and build mannually.
A new release to npm would be much appreciated!
When normalizing data by object key, a List is returned when a Map is better suited.
const json = {
foo: 'foo',
data: [
{ id: 1, name: 'Foo' },
{ id: 2, name: 'Bar' },
{ id: 3, name: 'Baz' }
]
};
const record = Record({
id: null,
name: null
});
const schema = new Schema('articles', {
record
});
const normalized = normalize(json, {
data: arrayOf(schema)
});
AFTER normalizr-immutable:
{
"entities":{ // Record
"articles":{ // Record
"1":{"id":1,"name":"Foo"},
"2":{"id":2,"name":"Bar"},
"3":{"id":3,"name":"Baz"}
}
},
"result":[ // List ???
["foo", "foo"],
["data", [1, 2, 3]]
]
}
AFTER normalizr:
{
"entities":{
"articles":{
"1":{"id":1,"name":"Foo"},
"2":{"id":2,"name":"Bar"},
"3":{"id":3,"name":"Baz"}
}
},
"result":{
"foo":"foo",
"data":[1, 2, 3]
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.