const { fromJS } = require("immutable");
// opportunities with repeated relationships and stages
const fetchedOpportunities = [
{_id: "foo", relationship: { _id: "relFoo", name: "Arya" }, stage: { _id: "stgFoo", name: "A girl" }},
{_id: "bar", relationship: { _id: "relBar", name: "Bran" }, stage: { _id: "stgBar", name: "Climber" }},
{_id: "baz", relationship: { _id: "relFoo", name: "Arya" }, stage: { _id: "stgBaz", name: "No one" }},
{_id: "qux", relationship: { _id: "relBar", name: "Bran" }, stage: { _id: "stgQux", name: "Three-eyed Raven" }},
{_id: "quux", relationship: { _id: "relFoo", name: "Arya" }, stage: { _id: "stgBaz", name: "No one" }}
];
// build a map containing unique opportunities, relationships, and stages that should be cached
const cacheData = fetchedOpportunities.reduce((acc, opportunity) => {
const {
_id,
relationship: { _id: relationshipId } = {},
stage: { _id: stageId } = {}
} = opportunity;
// immutable is nice because it always returns a new structure with capability of chaining additional commands
// 1. create a new object based on opportunity, overwrite relationship and stage with objects or null
// 2. map the opportunity by id
// 3. if we have a relationship id, map the relationship by its id
// use update here because we need to conditionally add the relationship
// update's `updater` function gets the current value as its parameter
// if we have a relationshipId, use `set` to update the current value of `relationships`
// otherwise, return the current value
// 4. if we have a stage id, map the stage by its id
// (again, use updage because we need to conditionally add the stage)
// same pattern as above
const opportunityData = {
...opportunity,
relationship: relationshipId != null ? { _id: relationshipId } : null,
stage: stageId != null ? { _id: stageId } : null
};
return acc
.setIn(["opportunities", _id], opportunityData)
.update("relationships", relationships =>
relationshipId != null
? relationships.set(relationshipId, opportunity.relationship)
: relationships
)
.update("stages", stages =>
stageId != null ? stages.set(stageId, opportunity.stage) : stages
);
}, fromJS({ opportunities: {}, relationships: {}, stages: {} }));