Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't resolve all parameters for DataService Angular

Tags:

angular

I am trying to create a generic service. I found this article: https://medium.com/@krishna.acondy/a-generic-http-service-approach-for-angular-applications-a7bd8ff6a068 which I have used to create my DataService which looks like this:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

import { environment } from '../../../environments/environment';
import { Resource } from '../models/resource';
import { Serializer } from '../interfaces/serializer';

const API_URL = environment.apiUrl;

@Injectable()
export class DataService<T extends Resource> {

  constructor(
    private httpClient: HttpClient,
    private endpoint: string,
    private serializer: Serializer) {}

  public create(item: T): Observable<T> {
    return this.httpClient
      .post<T>(`${API_URL}/${this.endpoint}`, this.serializer.toJson(item))
      .map(data => this.serializer.fromJson(data) as T);
  }

  public update(item: T): Observable<T> {
    return this.httpClient
      .put<T>(`${API_URL}/${this.endpoint}/${item.id}`,
        this.serializer.toJson(item))
      .map(data => this.serializer.fromJson(data) as T);
  }

  read(id: number): Observable<T> {
    return this.httpClient
      .get(`${API_URL}/${this.endpoint}/${id}`)
      .map((data: any) => this.serializer.fromJson(data) as T);
  }

  list(): Observable<T[]> {
    return this.httpClient
      .get(`${API_URL}/${this.endpoint}`)
      .map((data: any) => this.convertData(data.items));
  }

  delete(id: number) {
    return this.httpClient
      .delete(`${API_URL}/${this.endpoint}/${id}`);
  }

  private convertData(data: any): T[] {
    return data.map(item => this.serializer.fromJson(item));
  }
}

My Serializer looks like this:

import { Resource } from "../models/resource";

export interface Serializer {
    fromJson(json: any): Resource;
    toJson(resource: Resource): any;
}

And my Resource looks like this:

export class Resource {
    id: number
}

If I try to run my project, I get an error stating:

Uncaught Error: Can't resolve all parameters for DataService: ([object Object], [object Object], ?).

It looks like it is having issues with the Serializer, but I can't see why. I have commented out the spec file, so it isn't being used there and currently the DataService has not been extended, so I am not sure why it is moaning. Does anyone know why?


The suggestion was to create a new serivce that extends the DataService (I had already tried that, but before I posted this question I deleted it to see if it was causing the issue. Now I have re-created it and I am still getting the same error.

Here is my new class:

import { Injectable } from '@angular/core';
import { DataService } from './data.service';
import { HttpClient } from '@angular/common/http';

import { CategorySerializer } from '../models/category-serializer';
import { Category } from '../models/category';

@Injectable()
export class CategoryService extends DataService<Category> {

  constructor(httpClient: HttpClient) {
    super(
      httpClient,
      'categories',
      new CategorySerializer()
    );
  }

}

and Category looks like this:

import { Resource } from "./resource";

export class Category extends Resource {
    name: string
}

and the most import CategorySerializer looks like this:

import { Serializer } from "../interfaces/serializer";
import { Category } from "./category";

export class CategorySerializer implements Serializer {
    fromJson(json: any): Category {
      const model = new Category();
      model.id = json.id;
      model.name = json.name;  
      return model;
    }

    toJson(model: Category): any {
      return {
        id: model.id,
        name: model.name
      };
    }
}

yet I still have the same error :(

like image 933
r3plica Avatar asked Mar 09 '26 05:03

r3plica


1 Answers

The reason Angular is having trouble resolving the Serializer is because there is no implementation of a Serializer object.

The serializer has been defined as an interface which can be thought of as an abstract class (it cannot be called directly but instead acts as a 'template' for classes to conform to). In order to use the serializer within a class you need to instantiate it to make it a real object that can be interacted with. To do this you need to create a class that extends your serializer interface and then call to that.

In the example you posted, this has been made to work generically which removes some clarity from what is happening but essentially you need a concrete class to implement (they use PizzaSerializer)

enter image description here

When they instantiate the service itself they pass through a newly instantiated version of a Serializer (with the new key word) which will be used by the constructor as a type of Serializer.

Make sure you have a serializer that extends your Serializer class and that is passed to the Service constructor.

like image 60
Jack Scott Avatar answered Mar 11 '26 08:03

Jack Scott



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!