Home > OS >  Angular HTTP client GeoServer REST API mapping
Angular HTTP client GeoServer REST API mapping

Time:07-07

I'm using an Angular service to interact with the GeoServer REST API. The JSON response for getting layers is:

{
    "layers": {
        "layer": [
            {
                "name": "facility",
                "href": "http://localhost/geoserver/rest/workspaces/unacorn/layers/facility.json"
            },
            {
                "name": "opensky",
                "href": "http://localhost/geoserver/rest/workspaces/unacorn/layers/opensky.json"
            }
        ]
    }
}

My service method is:

public getLayers(): Observable<Layer[]> {
    let layerUrl = this.geoUrl   "/rest/workspaces/unacorn/layers";
    
    return this.http.get<Layer[]>(layerUrl, this.httpOptions)
      .pipe(
        map(response => {
          return {
            layers: <Layer[]>response.layers.layer
          }
        })
      )
  }

The caller code is:

private layers: Layer[]
 
this.geoService.getLayers().subscribe((response: Layer[]) => {
  this.layers = response;
});

The model for a layer is:

export interface Layer {
  name: string
  href: string
}

The data is getting returned correctly, but I can't get the mapping to my model to work properly. This is the error I'm seeing at compile time:

Type 'Observable<{ data: any; }>' is not assignable to type 'Observable<Layer[]>'. Type '{ data: any; }' is missing the following properties from type 'Layer[]': length,pop, push, concat, and 29 more.ts(2322)

All the docs and posts I've read show casting to the model interface is the correct approach. I'm likely just missing something simple. TIA for any assistance!

CodePudding user response:

The error is that line:

return this.http.get<Layer[]>(layerUrl, this.httpOptions)

You are writing that the return type from the GET should be Layer[] but it is not. It is an Object with a property Layers. The type of GET (value in <>) should be the type that the API returns. To solve the issue, you can create an interface representing the type of the return value. Solution:

export interface ApiResponse {
  layers: {
    layer: Layer[]
  }
}

public getLayers(): Observable<Layer[]> {
  let layerUrl = this.geoUrl   "/rest/workspaces/unacorn/layers"; 
  return this.http.get<ApiResponse>(layerUrl, this.httpOptions)
    .pipe(
      map(response => {
        return response.layers.layer;
      })
    )
}

  • Related