title: How to use typescript protobuf generated files in a gRPC angular application
body: <h2>Summarize the problem</h2>
  
  <p>I'm learning how to use gRPC, and wanted to try to do a client-server connection. The server (in Elixir) works, though I had a few problems. But as I am mainly a back end developer, I have way more troubles with implementing it in Angular, and would appreciate to have some help.</p>
  
  <p>I am using <em>Angular 8.2.9</em>, <em>Angular CLI 8.3.8</em> and <em>Node 10.16.0</em> for this project.</p>
  
  <h2>What have I already done?</h2>
  
  <ol>
  <li>Created a new angular cli project with <code>ng new test-grpc</code></li>
  <li>Generated a module and a component with <code>ng g...</code>, and modify the base routing to have working pages and urls.</li>
  <li>Installed Protobuf and gRPC libraries <code>npm install @improbable-eng/grpc-web @types/google-protobuf google-protobuf grpc-web-client protoc ts-protoc-gen --save</code></li>
  <li>Tooked the <code>.proto</code> file from my Elixir code and copied it in a folder <code>src/proto</code></li>
  <li>Added a <code>protoc</code>command in the package.json <code>scripts</code> : <code>
  "protoc": "protoc --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts.cmd --js_out=import_style=commonjs,binary:src/app/proto-gen --ts_out=service=true:src/app/proto-ts -I ./src/proto/ ./src/proto/*.proto"</code></li>
  <li>Called the command to generate the js and ts files  found in <code>src/app/proto-ts</code> and <code>src/app/proto-js</code></li>
  <li>Replaced any <code>_</code> with <code>-</code> in the names of the generated files.</li>
  <li>Then I tried to add the following code in a ngOnInit: <a href="https://github.com/improbable-eng/grpc-web/tree/master/client/grpc-web#usage-overview" rel="noreferrer">https://github.com/improbable-eng/grpc-web/tree/master/client/grpc-web#usage-overview</a> such as:</li>
  </ol>
  
  <pre class="lang-js prettyprint-override"><code>const getBookRequest = new GetBookRequest();
  getBookRequest.setIsbn(60929871);
  grpc.unary(BookService.GetBook, {
    request: getBookRequest,
    host: host,
    onEnd: res =&gt; {
      const { status, statusMessage, headers, message, trailers } = res;
      if (status === grpc.Code.OK &amp;&amp; message) {
        console.log("all ok. got book: ", message.toObject());
      }
    }
  });
  </code></pre>
  
  <p>I tried:</p>
  
  <ul>
  <li>To create the Request in the constructor arguments.</li>
  <li>To find how to add typescript files (I only find ways to add javascript files in a angular project, and the generated javascript are way heavier than the typescript, and don't have any explanation).</li>
  <li>To understand what the jspb.Message is (I still don't, but I think it is linked to this file: <a href="https://github.com/protocolbuffers/protobuf/blob/master/js/message.js" rel="noreferrer">https://github.com/protocolbuffers/protobuf/blob/master/js/message.js</a>)</li>
  <li>Tried to find a tutorial on how to implement rGPD in an angular app (404 none found)</li>
  </ul>
  
  <h2>The .proto file, the two typescript generated files and the component trying to use them</h2>
  
  <p>The .proto file ():</p>
  
  <pre class="lang-cpp prettyprint-override"><code>// src/proto/user.proto
  syntax = "proto3";
  
  service UserService {
    rpc ListUsers (ListUsersRequest) returns (ListUsersReply);
  }
  
  message ListUsersRequest {
    string message = 1;
  }
  
  
  message ListUsersReply {
    repeated User users = 1;
  }
  
  message User {
    int32 id = 1;
    string firstname = 2;
  }
  </code></pre>
  
  <p>The typescript generated code (2 files):</p>
  
  <pre class="lang-js prettyprint-override"><code>// src/app/proto-ts/user-pb.d.ts
  
  import * as jspb from "google-protobuf";
  
  export class ListUsersRequest extends jspb.Message {
    getMessage(): string;
    setMessage(value: string): void;
  
    serializeBinary(): Uint8Array;
    toObject(includeInstance?: boolean): ListUsersRequest.AsObject;
    static toObject(includeInstance: boolean, msg: ListUsersRequest): ListUsersRequest.AsObject;
    static extensions: {[key: number]: jspb.ExtensionFieldInfo&lt;jspb.Message&gt;};
    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo&lt;jspb.Message&gt;};
    static serializeBinaryToWriter(message: ListUsersRequest, writer: jspb.BinaryWriter): void;
    static deserializeBinary(bytes: Uint8Array): ListUsersRequest;
    static deserializeBinaryFromReader(message: ListUsersRequest, reader: jspb.BinaryReader): ListUsersRequest;
  }
  
  export namespace ListUsersRequest {
    export type AsObject = {
      message: string,
    }
  }
  
  export class ListUsersReply extends jspb.Message {
    clearUsersList(): void;
    getUsersList(): Array&lt;User&gt;;
    setUsersList(value: Array&lt;User&gt;): void;
    addUsers(value?: User, index?: number): User;
  
    serializeBinary(): Uint8Array;
    toObject(includeInstance?: boolean): ListUsersReply.AsObject;
    static toObject(includeInstance: boolean, msg: ListUsersReply): ListUsersReply.AsObject;
    static extensions: {[key: number]: jspb.ExtensionFieldInfo&lt;jspb.Message&gt;};
    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo&lt;jspb.Message&gt;};
    static serializeBinaryToWriter(message: ListUsersReply, writer: jspb.BinaryWriter): void;
    static deserializeBinary(bytes: Uint8Array): ListUsersReply;
    static deserializeBinaryFromReader(message: ListUsersReply, reader: jspb.BinaryReader): ListUsersReply;
  }
  
  export namespace ListUsersReply {
    export type AsObject = {
      usersList: Array&lt;User.AsObject&gt;,
    }
  }
  
  export namespace User {
    export type AsObject = {
      id: number,
      firstname: string,
    }
  }
  </code></pre>
  
  <pre class="lang-js prettyprint-override"><code>// src/app/proto-ts/user-pb-service.d.ts
  import * as user_pb from "./user-pb";
  import {grpc} from "@improbable-eng/grpc-web";
  
  type UserServiceListUsers = {
    readonly methodName: string;
    readonly service: typeof UserService;
    readonly requestStream: false;
    readonly responseStream: false;
    readonly requestType: typeof user_pb.ListUsersRequest;
    readonly responseType: typeof user_pb.ListUsersReply;
  };
  
  export class UserService {
    static readonly serviceName: string;
    static readonly ListUsers: UserServiceListUsers;
  }
  
  export type ServiceError = { message: string, code: number; metadata: grpc.Metadata }
  export type Status = { details: string, code: number; metadata: grpc.Metadata }
  interface UnaryResponse {
    cancel(): void;
  }
  interface ResponseStream&lt;T&gt; {
    cancel(): void;
    on(type: 'data', handler: (message: T) =&gt; void): ResponseStream&lt;T&gt;;
    on(type: 'end', handler: (status?: Status) =&gt; void): ResponseStream&lt;T&gt;;
    on(type: 'status', handler: (status: Status) =&gt; void): ResponseStream&lt;T&gt;;
  }
  interface RequestStream&lt;T&gt; {
    write(message: T): RequestStream&lt;T&gt;;
    end(): void;
    cancel(): void;
    on(type: 'end', handler: (status?: Status) =&gt; void): RequestStream&lt;T&gt;;
    on(type: 'status', handler: (status: Status) =&gt; void): RequestStream&lt;T&gt;;
  }
  interface BidirectionalStream&lt;ReqT, ResT&gt; {
    write(message: ReqT): BidirectionalStream&lt;ReqT, ResT&gt;;
    end(): void;
    cancel(): void;
    on(type: 'data', handler: (message: ResT) =&gt; void): BidirectionalStream&lt;ReqT, ResT&gt;;
    on(type: 'end', handler: (status?: Status) =&gt; void): BidirectionalStream&lt;ReqT, ResT&gt;;
    on(type: 'status', handler: (status: Status) =&gt; void): BidirectionalStream&lt;ReqT, ResT&gt;;
  }
  
  export class UserServiceClient {
    readonly serviceHost: string;
  
    constructor(serviceHost: string, options?: grpc.RpcOptions);
    listUsers(
      requestMessage: user_pb.ListUsersRequest,
      metadata: grpc.Metadata,
      callback: (error: ServiceError|null, responseMessage: user_pb.ListUsersReply|null) =&gt; void
    ): UnaryResponse;
    listUsers(
      requestMessage: user_pb.ListUsersRequest,
      callback: (error: ServiceError|null, responseMessage: user_pb.ListUsersReply|null) =&gt; void
    ): UnaryResponse;
  }
  </code></pre>
  
  <p>The attempt to use them in a component file:</p>
  
  <pre class="lang-js prettyprint-override"><code>// src/app/modules/user/pages/list/list.component.ts
  import { Component, OnInit } from '@angular/core';
  import { grpc } from "@improbable-eng/grpc-web";
  
  import { UserService } from '../../../../proto-ts/user-pb-service.d'
  import { ListUsersRequest } from '../../../../proto-ts/user-pb.d'
  
  @Component({
    selector: 'app-list',
    templateUrl: './list.component.html',
    styleUrls: ['./list.component.scss']
  })
  export class ListComponent implements OnInit {
  
    constructor() { }
  
    ngOnInit() {
      const listUsersRequest = new ListUsersRequest();
      listUsersRequest.setMessage("Hello world");
  
      grpc.unary(UserService.ListUsers, {
        request: listUsersRequest,
        host: "0.0.0.0:50051",
        onEnd: res =&gt; {
          const { status, statusMessage, headers, message, trailers } = res;
          if (status === grpc.Code.OK &amp;&amp; message) {
            console.log("all ok. got the user list: ", message.toObject());
          } else {
            console.log("error");
          }
        }
      });
    }
  }
  </code></pre>
  
  <h2>Expected result and actual results</h2>
  
  <p><strong>I expect to be able to use non angular typescript code in a component (or a service).</strong>
  <strong>As the code above (but the component file) is generated, it shouldn't be modified</strong>, because any changes on the <code>.proto</code> file will overwrite any modification done in these two generated files.</p>
  
  <p>For now, I am blocked by these two error message, which appear depending of which file I saved last: <code>TypeError: _proto_ts_user_pb_d__WEBPACK_IMPORTED_MODULE_4__.ListUsersRequest is not a constructor</code> (if I save a protobuf generated file last, no error in the console) or <code>src\app\proto-ts\user-pb-service.d.ts and src\app\proto-ts\user-pb.d.ts is missing from the TypeScript compilation. Please make sure it is in your tsconfig via the 'files' or 'include' property.</code>(if I saved a angular file last, same error message in the console).</p>
  
  <p>Adding the 'files' or 'include' in the <code>tsconfig.json</code> (which is the generated by angular CLI without any modifications) create another error: <code>Refused to load the image 'http://localhost:4200/favicon.ico' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.</code></p>