Given this kind of relationship from
GET /projects/1
const response = {
id: 1,
name: 'Normalized Redux',
type: 'project',
task_lists: [
{
id: 1,
name: 'Todo',
type: 'task_list',
project_id: 1,
tasks: [
{id: 1, type: 'task', name: 'As a user I can normalize belongs_to relation', task_list_id: 1},
{id: 2, type: 'task', name: 'As a user I can register webhooks', task_list_id: 1},
{id: 3, type: 'task', name: 'As a user I can listen for task completion event', task_list_id: 1}
],
{
id: 2,
name: 'Doing',
type: 'task_list',
project_id: 1,
tasks: []
},
{
id: 1,
name: 'Done',
type: 'task_list',
project_id: 1,
tasks: []
}
}
]
}Given these schema definitions
const project = Schema('project')
const taskList = Schema('task_list')
const task = Schema('task')
task.define({
task_list: taskList
})
taskList.define({
tasks: arrayOf(task)
})
project.define({
task_lists: arrayOf(taskList)
})When normalized with normalize(response, project) I will get
{
entities: {
project: {
1: {
id: 1,
name: 'Normalized Redux',
type: 'project',
task_lists: [1]
}
},
task_list: {
1: {
id: 1
name: 'Todo',
type: 'task_list',
project_id: 1,
tasks: [1, 2, 3]
},
2: {
id: 2,
name: 'Doing',
type: 'task_list',
project_id: 1,
tasks: []
},
3: {
id: 3,
name: 'Done',
type: 'task_list',
project_id: 1,
tasks: []
}
},
task: {
1: {id: 1, type: 'task', name: 'As a user I can normalize belongs_to relation', task_list_id: 1},
2: {id: 2, type: 'task', name: 'As a user I can register webhooks', task_list_id: 1},
3: {id: 3, type: 'task', name: 'As a user I can listen for task completion event', task_list_id: 1}
}
},
result: [1]
}My reducers
const byIdReducer = (entity) => (state = {}, action) => {
if (action.hasOwnProperty('normalized') &&
action.normalized.entities.hasOwnProperty(entity)) {
return merge({}, state, action.normalized.entities[entity])
}
return state
}
const idsReducer = (entity) => (state = [], action) => {
if (action.hasOwnProperty('normalized') &&
action.entity === entity) {
return isArray(action.normalized.result)
? [...new Set([...state, ...action.normalized.result])]
: [...new Set([...state, action.normalized.result])]
}
return state
}If I make an API call to add a new task to a task list I get back a response like so
POST /task_lists/1/tasks
{
id: 4,
type: 'task',
name: 'As an admin I can delete projects',
task_list_id: 1
}If I normalize that with normalize(response, task). I'll get this:
{
entities: {
task: {
4: {
id: 4,
name: 'As an admin I can delete post',
task_list_id: 1
}
}
},
result: [4]
}This wont update the tasks references on entities.task_list[1].tasks and effectively makes the UI outdated
Taking note of the task_list_id reference
How do I propagate the changes entities.task_list[1].tasks as well?. I can't find an easy way that doesn't involve alot of boilerplate code for this with Redux and Normalizr.
Expected output:
{
entities: {
task: {
4: {
id: 4,
name: 'As an admin I can delete post',
task_list_id: 1
}
},
task_list: {
1: {
tasks: [4]
}
}
},
result: [4]
}