Below is a snippet of code that calls a Loopback API method with an array of values. The input values are correct, no errors are thrown on the API and the subscribe block runs as expected.
const newStudentGroups =
selectedStudentIds.map(sId => ({
studentId: sId,
groupId: this.group.id,
schoolId: this.curSchool.id,
programId: this.curProg.id,
}));
this.stuGroupApi.create(newStudentGroups)
.subscribe((newStu) => {
console.log(newStu.map(s=>s[0]));
});
However the values returned to the subscribe block as newStu appears as an object of the form:
{
0:{
studentId: 123,
groupId: 321,
schoolId: 1,
programId: 5
},
1:{
studentId: 132,
groupId: 322,
schoolId: 1,
programId: 5
},
2:{studentId: 143,
groupId: 331,
schoolId: 1,
programId: 5
}
}
I need an array of StudentGroup objects the same as I put in. I recognize that I can forkJoin individual calls to the API but that seems like a lot of network traffic vs a single call that could/should run as a batch on the DB.
I can't find much to suggest if I've done this wrong or if there's a canonical way to get this back into the form in which I sent it. Is this a bug? Am I running the call incorrectly?
EDIT: I've been inspecting the actual network requests and it looks like Loopback is actually returning the array as required. So this has to be the SDK on my end somewhere. Does @mean-expert/loopback-sdk-builder convert arrays to objects intentionally or did I misconfigure something? I'm on version"@mean-expert/loopback-sdk-builder": "^2.1.0-rc.10.5".
TL;DR
Use the createMany
function instead of create
.
Given way that @mean-expert/loopback-sdk-builder parses the responses in BaseLoopBackApi (it should be in services/core
), calling the create
method will attempt to parse the response back to the generic datatype for the service (maybe StudentGroup for your call?). However, this parsing will by default use Object.assign(this, data);
. This will unfortunately convert arrays into objects the way you show.
e.g.
Object.assign({}, ['hi', 'there'])
will yield
{ '0': 'hi', '1': 'there' }
However, @mean-expert/loopback-sdk-builder provides another default function to fix that issue for you. Just switch your call to use createMany
instead.
Hence:
const newStudentGroups = selectedStudentIds.map(sId => ({
studentId: sId,
groupId: this.group.id,
schoolId: this.curSchool.id,
programId: this.curProg.id,
}));
this.stuGroupApi.createMany(newStudentGroups)
.subscribe(newStus => {
console.log(newStus);
});
Given the response from the server, you can get a usable array back by running
this.stuGroupApi.create(newStudentGroups)
.map(newStu => Object.keys(newStu).map(i => newStu[i]))
.subscribe((newStu) => {
console.log(newStu.map(s=>s[0]));
});