grpc в javaScript - как избавиться от fieldsMap

Всем доброго времени. Никто не работал с grpc в ангуларе?

google_protobuf_struct_pb.Struct.toObject() даёт странный массив

{
  "fieldsMap": [
    [
      "value",
      {
        "nullValue": 0,
        "numberValue": 0,
        "stringValue": "Значение!",
        "boolValue": false
      }
    ]
  ]
}

Слов нет, как удобно получается

const data = this.field.data?.fieldsMap;
this.field.data?.fieldsMap[0][1]
if(data && data[0] && data[0][1] && data[0][1][FieldValueType.STRING]?.length > 0) {
    this.fieldValueType = FieldValueType.STRING;
}

Никто не знает, что это, и как с этим жить, учитывая, что Struct находятся в глубине jspb.Message и непосредственно вызвать у него .toJavaScript() не представляется возможным, приходится юзать весь jspb.Message.toObject()?? Лично я решил для себя проблему, переопределив один из методов мессег (Some - объект jspb.Message в сгенерированном через protoc коде, а getValue в нем дает Struct, который стандартно тоже приводится через toObject)

const SomeToObject = Some.toObject;

Some.toObject = function (includeInstance: boolean, msg: Some) : Some.AsObject
{
    const rowResult = SomeToObject(includeInstance, msg);
    rowResult.value = msg.getValue()?.toJavaScript();

    return rowResult;
};

Почему-то у jspb.Message метод toObject не в prototype и я получаю его в константу SomeToObject, затем я получаю стандартный результат через эту функцию, затем подменяю value, которое уже получено через toObject с fieldsMap, на новое, полученное через toJavaScript.

Вот здесь https://github.com/grpc/grpc-web/issues/315 тоже получают объек стандартным способо, а затем пробегается по результату, чтобы получить имена функций, получает их,приводит к строке - короче много телодвижений только, чтобы получить json. Такие дела.

Можно также переопределить сразу функцию google_protobuf_struct_pb.Struct.toObject, но у нас уже стоит некоторое количество костылей для fieldsMap и возможно, оно там где-то внутри grpc используется. Может кто-то знает менее костыльный способ?

jspb.Message.toObject вызывает toObject у всех своих потомков, в том числе и у тех, который Struct и не существует метода, чтобы сделать для jspb.Message - toObject, а для Struct - toJavaScript.

Вот допустим пришло мне сообщение со множеством разных параметров.

export class AnyResponse extends jspb.Message {
  getView(): View | undefined;
  setView(value?: View): OperationResponse;
  hasView(): boolean;
  clearView(): OperationResponse;

  getAnyParam(): string;
  setAnyParam(value: string): OperationResponse;
........

И допустим, где-то в глубине этой кучи данных есть значение value, которое тоже надо получить. response.getSome()?.getItems()?.getValue()?.toObject() даст нам значение вот в таком виде

"value": {
            "fieldsMap": [
              [
                "id",
                {
                  "nullValue": 0,
                  "numberValue": 1,
                  "stringValue": "",
                  "boolValue": false
                }
              ],
              [
                "anyNname",
                {
                  "nullValue": 0,
                  "numberValue": 0,
                  "stringValue": "Здесь строка",
                  "boolValue": false
                }
              ],

Это не то, что мне нужно, мне было бы гораздо удобнее получить нормальный объект. Если я применю response.getSome()?.getItems()?.getValue()?.toJavaScript(), то получится то, что нужно.

"value": {
            "id": 1,
            "name": "Здесь строка",
            .......
          }

Но мне необходимо конвертнуть в нормальный объект со значениями весь AnyResponse, который не имеет метода toJavaScript, а он сам и его дети вниз по цепочке являются наследниками jspb.Message и соответственно, имеют только toObject. А value уже google_protobuf_struct_pb.Struct и он может быть обработан через toJavaScript. Вообще-то там массив, и .getValue() нужно еще и циклом перебрать, например. Я пытаюсь упростить код и опустить ненужную информацию, чтобы проблема наглядно сохранилаь.


Ответы (0 шт):