Getting: “TypeError: this.get$BrowserClient is not

2019-09-05 02:11发布

问题:

I'm coding a modified version of the AngularDart tutorial. I'm adding a server call based on the example in the Developer Guide/HTTP Client. Instead of the memory service, I'm trying to connect to an actual server on the same machine. I've gotten it to work in plain Dart using HTTPRequest in my Rails application. In my new AngularDart standalone client, I get the error:

TypeError: this.get$BrowserClient is not a function

I suspect this may be happening because I never created the in memory server in main.dart. If so, what is the correct code to talk to a real server?

My service class:

import 'dart:async';
import 'dart:convert';

import 'package:angular2/core.dart';

import 'artist.dart';
import 'package:http/browser_client.dart';
import 'package:http/http.dart';

@Injectable()

class ArtistService {
  static const _artistsUrl = 'http://jazzcatold.loc/artists?page=1'; // URL to RAILS server
  final BrowserClient _http;
  ArtistService(this._http);

  Future<List<Artist>> getArtists() async {
    try {
      final response = await _http.get(_artistsUrl,
          headers: {'Accept': 'application/json'});
      final artists = _extractData(response)
          .map((value) => new Artist.fromJson(value))
          .toList();
      return artists;
    } catch (e) {
      throw _handleError(e);
    }
  }

...

My main.dart is:

import 'package:angular2/platform/browser.dart';
import 'package:jazzcat/app_component.dart';

main() {
  bootstrap(AppComponent);
}

The example has:

import 'package:angular2/core.dart';
import 'package:angular2/platform/browser.dart';
import 'package:http/browser_client.dart';

import 'package:server_communication/app_component.dart';
import "package:server_communication/hero_data.dart";

void main() {
  bootstrap(AppComponent, const [
    // in-memory web api provider
    const Provider(BrowserClient,
        useFactory: HttpClientBackendServiceFactory, deps: const [])
    // TODO: drop `deps` once fix lands for 
    // https://github.com/angular/angular/issues/5266
  ]);
}

Plan B

I tried this from the link given:

import 'package:http/http.dart' as http;


@Injectable()

class ArtistService {
  static const _artistsUrl = 'http://jazzcatold.loc/artists?page=1'; // URL to RAILS server

  Future<List<Artist>> getArtists() async {
    final response = await http.get(_artistsUrl, headers: {'Accept':    'application/json'});
    final artists = _extractData(response)
        .map((value) => new Artist.fromJson(value))
        .toList();
    return artists;
  }

I got the error:

EXCEPTION: Unsupported operation: IOClient isn't supported on this platform.

Plan C

I modified working code from another project:

import 'dart:html';

@Injectable()

class ArtistService {
  static const _artistsUrl = 'http://jazzcatold.loc/artists?page=1'; // URL to  RAILS server
  Map headers = {'Accept': 'application/json'};

  Future<List<Artist>> getArtists() async {
  final response = await HttpRequest.request(_artistsUrl, requestHeaders: headers);
  final artists = _extractData(response)
      .map((value) => new Artist.fromJson(value))
      .toList();
  return artists;
  }

When I check the network data on the Chrome inspector, I see the JSON data being returned. I'm getting the error:

html_dart2js.dart:3352 EXCEPTION: NoSuchMethodError: method not found:   'get$body' (J.getInterceptor$x(...).get$body is not a function) 

The code may not be a fit for the getArtists structure.

回答1:

You can't import http/browser_client.dart in a standalone application. That's only supposed to be used for browser applications.

See https://pub.dartlang.org/packages/http for examples how to use it for standalone applications.



回答2:

The answer is a working version of Plan C above.

import 'dart:async';
import 'dart:convert';
import 'package:angular2/core.dart';

import 'artist.dart';
import 'dart:html';


@Injectable()

class ArtistService {
  static const url = 'http://jazzcatold.loc/artists?page=1'; // URL to RAILS server
  Map headers = {'Accept': 'application/json'};

  Future<List<Artist>> getArtists() async {
    HttpRequest response = await HttpRequest.request(url, requestHeaders: headers);
    List data = JSON.decode(response.responseText);
    final artists = data
          .map((value) => new Artist.fromJson(value))
          .toList();
    return artists;
  }

I rolled up the _extractData method into this one. I also coded it more precisely based on Günter's advice elsewhere. The getBody error above was in the extractData method that is not shown.