3

My Angular 4 application consume Spring Data REST API HATEOAS server, I am using HttpClient and I see that it returns Object instead of any like http. I read this question: Why does the httpclient in angular 4.3 return Object instead of any? and I got it. I have complex json with many fields like this:

{
  "_embedded": {
    "customers": [
      {
        "sid": "c44fdb6f-9b7c-4f75-8d4c-7542f54037b7",
        "createdDate": "2017-08-01T13:06:23Z",
        "lastModifiedDate": "2017-08-01T13:06:23Z",
        "lastModifiedBy": "admin",
        "name": "Customer 1",
        "username": "customer1",
        "address": "Via xxxxx",
        "city": "Adria",
        "landlinePhone": "+39042000000",
        "mobilePhone": null,
        "email": "email@test.it",
        "fax": null,
        "vatNumber": "IT01000020295",
        "taxCode": null,
        "iban": null,
        "swift": null,
        "enableEcommerce": true,
        "balance": 0,
        "enabled": true,
        "new": false,
        "_links": {
          "self": {
            "href": "....:8080/api/v1/customers/1"
          },
          "customer": {
            "href": "....:8080/api/v1/customers/1"
          },
          "movements": {
            "href": "....:8080/api/v1/customers/1/movements"
          },
          "country": {
            "href": "....:8080/api/v1/customers/1/country"
          }
        }
      }
    ]
  },
  "_links": {
    "self": {
      "href": "....:8080/api/v1/customers{?page,size,sort}",
      "templated": true
    },
    "profile": {
      "href": "....:8080/api/v1/profile/customers"
    },
    "search": {
      "href": "....:8080/api/v1/customers/search"
    }
  },
  "page": {
    "size": 20,
    "totalElements": 1,
    "totalPages": 1,
    "number": 0
  }
}

HttpClient does not permit to do response.page.totalElements because, like I said, the response type is a Object and not of type any. I am wondering which is the best way to accomplish my goal; I have 2 ideas in mind:

  • Cast the response to any. In this case I would be able to access to fields without any typecheck of course.

  • Create several objects to map the HATEOAS response: probably I would need at least 2-3 interfaces and than 1 class for each model entity. This approach seems quite complex, maybe overkill compared to the first solution and I always need a cast from object to my specific entity model;this means I could have a runtime exception due a wrong typecast.

Could you give me some advice and best practice to reach my goal and follow the idea angular's team drew?

Alessandro Celeghin
  • 4,039
  • 14
  • 49
  • 95

1 Answers1

5

I have the same problem and I found one possible solution:

// Java: Spring Data REST Repository
@RepositoryRestResource(collectionResourceRel = "result", path = "customers")
public interface CustomerRepository extends PagingAndSortingRepository<Customer, Long> {
}

// TypeScript model
export interface ListResult<T> {
   _embedded: EmbeddedList<T>;
  _links: any;
  page: any;
}

export interface EmbeddedList<T> {
  results: T[];
}

export class Customer{
  name: String;
  ... bla bla ...
}

// AJAX Call
http.get('/api/customers').subscribe(response => {
  const customers: Customer[] = response._embedded.results;
});

All repositories must have collectionResourceRel="results".

Neeraj Kumar
  • 771
  • 2
  • 16
  • 37
Martin Mahr
  • 53
  • 1
  • 4