kukkuz kukkuz - 4 months ago 26
JSON Question

Resolve References in JSON : Javascript / JSON

I have the following sample JSON coming from a server. Duplicate objects are being internally referred to by an id (see the JSON below).

[
{ "id": 1,
"agent": {
"id": 1,
"firstName": "gghg",
"lastName": "gh",
"phone": "4543534",
"admin": true
},
"user":"agent@gmail.com"
},
{ "id": 2,
"agent": 1, // here I want the full object and not the Id
"user":"agent1@gmail.com"
}
]


Question:
How do I resolve the objects referred to in this fashion given a random JSON object?

(For instance, for the sample JSON above, I will have the below output:)

[
{ "id": 1,
"agent": {
"id": 1,
"firstName": "gghg",
"lastName": "gh",
"phone": "4543534",
"admin": true
},
"user":"agent@gmail.com"
},
{ "id": 2,
"agent": {
"id": 1,
"firstName": "gghg",
"lastName": "gh",
"phone": "4543534",
"admin": true
},
"user":"agent1@gmail.com"
}
]

Answer

Basically a single loop proposal, which collects unresolved links and if found the it replaces the open parts with the object.

var data = [{ "id": 1, "agent": { "id": 1, "firstName": "gghg", "lastName": "gh", "phone": "4543534", "admin": true }, "user": "agent@gmail.com" }, { "id": 2, "agent": 1, "user": "agent1@gmail.com" }];

data.forEach(function (a) {
    if (typeof a.agent === 'object') {
        this[a.agent.id] = this[a.agent.id] || {};
        this[a.agent.id].data = a.agent;
        this[a.agent.id].update && this[a.agent.id].update.forEach(function (b) {
            b.agent = a.agent;
        });
        return;
    } 
    this[a.agent] = this[a.agent] || {};
    if (this[a.agent].data) {
        a.agent = this[a.agent].data;
        return;
    }
    this[a.agent].update = this[a.agent].update || [];
    this[a.agent].update.push(a);
}, Object.create(null));

console.log(data);

Edit, a more generic version for unknown property references.

var data = [
        { id: 1, agent: { id: 1, firstName: "gghg", lastName: "gh", phone: "4543534", admin: true }, user: "agent@gmail.com", abc: 2 },
        { id: 2, agent: 1, user: "agent1@gmail.com", abc: { id: 2, text: 'blabla' } },
        { id: 3, agent: { id: 1, firstName: "gghg", lastName: "gh", phone: "4543534", admin: true }, user: "agent@gmail.com" },
    ];

data.forEach(function (a) {
    Object.keys(a).forEach(function (k) {
        if (typeof a[k] === 'object' && 'id' in a[k]) {
            this[a[k].id] = this[a[k].id] || {};
            this[a[k].id].data = a[k];
            this[a[k].id].update && this[a[k].id].update.forEach(function (b) {
                b[k] = a[k];
            });
            return;
        }
        this[a[k]] = this[a[k]] || {};
        if (this[a[k]].data) {
            a[k] = this[a[k]].data;
            return;
        }
        this[a[k]].update = this[a[k]].update || [];
        this[a[k]].update.push(a);
    }, this);
}, Object.create(null));

console.log(data);