X Tutup
The Wayback Machine - https://web.archive.org/web/20211111021536/https://github.com/angular/angular/issues/44143
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide first class HTTP streaming API as part of @angular/commom/http package #44143

Open
prabh-62 opened this issue Nov 11, 2021 · 0 comments
Open

Comments

Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant
@prabh-62
Copy link

@prabh-62 prabh-62 commented Nov 11, 2021

Which @angular/* package(s) are relevant/releated to the feature request?

common

Description

This feature request is to provide a first class HTTP streaming API as part of @angular/commom/http package. This will enable sending large amount of data in batches to client-side from server-side and display data on UI as soon as it arrives over the wire.

This is how the above scenario can be achieved using current tools.

  • Install dotnet 6 SDK
  • dotnet --version
    6.0.100
  • dotnet new web --name ShoppingAPI (Create new dotnet API)
  • Edit Program.cs and add /stream endpoint
        var builder = WebApplication.CreateBuilder(args);
        builder.Services.AddCors(options => options.AddPolicy(name: "mypolicy", builder => builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()));
        
        var app = builder.Build();
        
        app.MapGet("/", () => "Hello World!");
        
        app.MapGet("/stream", () =>
        {
            static async IAsyncEnumerable<object> GetProducts(int totalItems)
            {
                for (int i = 0; i < totalItems; i++)
                {
                    await Task.Delay(1000).ConfigureAwait(false);
                    yield return new { Id = i };
                }
            }
            return Results.Ok(GetProducts(10));
        });
        
        app.UseCors("mypolicy");
        app.Run();
  • dotnet run
dotnet-6_api_stream.mov
  • npx @angular/cli new admin-console --style css --routing false (Now, create a new angular 13 application)
  • Edit src/app/app.component.html
      <ul>
          <li *ngFor="let product of products">{{ product.id }}</li>
      </ul>
  • Edit src/app/app.component.ts.
        @Component({
          selector: 'app-root',
          templateUrl: './app.component.html',
          styleUrls: ['./app.component.css'],
          changeDetection: ChangeDetectionStrategy.OnPush,
        })
        export class AppComponent implements OnInit {
          public products: { id: number }[] = [];
        
          constructor(private readonly cd: ChangeDetectorRef) {}
        
          public ngOnInit(): void {
            this.getListOfProducts();
          }
        
          private async getListOfProducts(): Promise<void> {
            const response = await fetch('http://localhost:5005/stream', {
              allowHTTP1ForStreamingUpload: true,
            } as any);
            if (response.body == null) {
              throw new Error('Not possible in current scenario');
            }
            const reader = response.body.getReader();
        
            const products = this.products;
            const cd = this.cd;
            async function printStream() {
              const { done, value } = await reader.read();
              const textDecoder = new TextDecoder();
              if (done) {
                return;
              }
              const stringValue = textDecoder.decode(value);
              const trimmedValue = stringValue
                .replace('[{', '{')
                .replace('},', '}')
                .replace(',{', '{')
                .replace('}]', '}');
              products.push(JSON.parse(trimmedValue) as { id: number });
              cd.markForCheck();
              await printStream();
            }
            await printStream();
          }
        }
  • npm start (Run the UI project)
angular_app_stream_http.mov

System Info

  • Browser: Google Chrome Version 95.0.4638.69 (Official Build) (x86_64)
  • OS: macOS 12.0.1

Proposed solution

Provide the similar streaming functionality of fetch API as part of @angular/common/http package

Alternatives considered

using fetch API for now.

CanIUse data on ReadableStream
fetch_readable_stream

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
X Tutup