My Proto file looks like this -
message Todos {
repeated Todo todos = 1;
}
message Todo {
int32 id = 1;
string name = 2;
bool done = 3;
}
It es works fine when I send {todos: [...]} from the server, but gets an empty object {} when directly sending an array.
Server
getAll(_, callback) {
console.log(todos);
return callback(null, { todos });
}
Client
client.getAll({}, function (err, res) {
if (err) {
return console.log(err);
}
console.log('todos: ');
return console.log(res);
});
Versions -
- @grpc/proto-loader - ^0.1.0
- grpc - ^1.13.0
My Proto file looks like this -
message Todos {
repeated Todo todos = 1;
}
message Todo {
int32 id = 1;
string name = 2;
bool done = 3;
}
It es works fine when I send {todos: [...]} from the server, but gets an empty object {} when directly sending an array.
Server
getAll(_, callback) {
console.log(todos);
return callback(null, { todos });
}
Client
client.getAll({}, function (err, res) {
if (err) {
return console.log(err);
}
console.log('todos: ');
return console.log(res);
});
Versions -
- @grpc/proto-loader - ^0.1.0
- grpc - ^1.13.0
-
Are you saying that you're getting different results if you pass
{todos}
instead of{todos: todos}
, or is there some other difference between the two situations? Istodos
an empty array, and if so have you tried following the suggestions in this GitHub issue? – murgatroid99 Commented Jul 19, 2018 at 19:45 - @murgatroid99 Thanks for the suggestion, but I've checked my server and todos is an non-empty array. When sending { todos } or { todos : todos }, my client gets an object. But when I send todos ( as a direct array ) it gets an empty Object. – Shobhit Chittora Commented Jul 20, 2018 at 12:18
- Can this be because of how I've define the proto? – Shobhit Chittora Commented Jul 20, 2018 at 12:18
3 Answers
Reset to default 4In my case I was trying to return an array and it seems you always have to return an object....
hero.proto
syntax = "proto3";
package hero;
service HeroService {
rpc GetHeroById(HeroById) returns (Hero) {}
rpc ListHeroesById(HeroById) returns (HeroList) {}
}
message HeroById {
int32 id = 1;
}
message Hero {
int32 id = 1;
string name = 2;
}
message HeroList {
repeated Hero heroes = 1;
}
hero.controller.ts
@GrpcMethod('HeroService')
listHeroesById(data: HeroById, metadata: any): object {
const items = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Doe' },
{ id: 3, name: 'Billy' },
];
// make sure you return an object, even if you want an array!
return { heroes: items.filter(({ id }) => id === data.id) };
}
Check out my example TypeScript project here:
https://github./kmturley/angular-nest-grpc
If I understand correctly, you are having problems if you send just the array todos
, instead of an object containing that array. Sending just the array is simply an invalid use of the API. Protobuf services always send protobuf messages, so you have to pass an actual message object, and not a single field of that object.
If you use grpc.load
then you can send back an array:
callback(null, todos);
If you use protoLoader.loadSync
and grpc.loadPackageDefinition
, then you need to send back:
callback(null, { todos: todos });