Johnny Bonami
Johnny Bonami

Reputation: 18

Is there a way to refactor similar angular services?

In the case I have these two angular services userService and carService which are basically doing the same thing for two different objects (Here I take the data from json files). Is there a way to refactor this not to repeat twice almost the same code ?

export class UserService {

    constructor(private http: HttpClient) { }

    getUsers(): Observable<UserDto[]> {
        return this.http.get<UserDto[]>('../../assets/users.json');
    }
    //getUserById(){
    }
}

export class CarService {

    constructor(private http: HttpClient) { }

    getCars(): Observable<CarDto[]> {
        return this.http.get<CarDto[]>('../../assets/cars.json');
    }
    //getCarById(){
    }
}

Upvotes: 0

Views: 159

Answers (3)

meriton
meriton

Reputation: 70564

If you're after static JSON assets, you could simply import them - but you're probably after actual API requests?

In that case, if the operations are indeed very similar, a generic super class might be the way to go:

abstract class Repository<T> {
  constructor(protected http: HttpClient) {}

  abstract readonly basePath: string;

  getAll() {
    return this.http.get<T[]>(this.basePath);
  }

  getById(id: string) {
    return this.http.get<T>(`${this.basePath}/{$id}`);
  }
}

which cuts down the declaration of the concrete classes to the bare minimum:

class UserRepository extends Repository<User> {
  basePath = "users";
}

class CarRepository extends Repository<Car> {
  basePath = "car";
}

Upvotes: 2

Maybe try this approach:

const uris = {
  user: 'api/users',
  car: 'api/cars',
};

export class CommonService {
  private ULIs = uris;

  constructor(private http: HttpClient) {}

  getEntities(type: string): Observable<any[]> {
    return this.http.get(this.ULIs[type]);
  }

  getEntitiyById(type: string): Observable<any> {
    return this.http.get(`${this.ULIs[type]}/id`);
  }
}

But IMHO, it's not okay... maybe it's useful in start of application, but in a few months of developing you will refactor it too.

Upvotes: 0

dota2pro
dota2pro

Reputation: 7856

Use one service with 2 functions

export class UserService {
    const urls = {
     user: '../../assets/users.json',
      car: '../../assets/cars.json'
}
    constructor(private http: HttpClient) { }

    getUsers(): Observable<UserDto[]> {
        return this.http.get<UserDto[]>(urls.user);
    }
   getCars(): Observable<CarDto[]> {
       return this.http.get<CarDto[]>(urls.car);
    }

    }
}

Upvotes: 0

Related Questions