最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Working with a message having repeated field - Stack Overflow

programmeradmin2浏览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

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
Share Improve this question asked Jul 19, 2018 at 18:34 Shobhit ChittoraShobhit Chittora 1,27910 silver badges13 bronze badges 3
  • 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? Is todos 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
Add a ment  | 

3 Answers 3

Reset to default 4

In 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 });
发布评论

评论列表(0)

  1. 暂无评论