user15878006
user15878006

Reputation:

Refactoring duplicated code in Angular typescript

I need to refactor duplicated code but I don't know how I would do it.

I have two methods that basically call the same service (I need to call the same request because of pagination) but now it looks ugly because of duplicated code. How can I make this better?

    getStockData(id: string): Observable<{
    searchResult: IStockResult[];
    searchCount: number;
}> {
    return this.service
        .search(
            id,
            this.service.getSearchMetaDefaults()
        )
        .pipe(
            map(response => {
                return {
                    searchResult: response, 
                    searchCount: response.meta.totalResourceCount
                };
            })
        );

Upvotes: 0

Views: 295

Answers (1)

Barremian
Barremian

Reputation: 31105

There are possibly multiple elegant solutions to the question. I could propose the following quick changes

  1. Define types for the objects used (eg. using TS interface)
export interface ISearch { 
  searchResult: IStockResult[]; 
  searchCount: number; 
}

export interface IMeta {
  pagination: {
    size: number;
    index: number;
  },
  sorting: {
    order: string;
    attribute: string;
  }
}
  1. Define optional parameters using ?: and send the argument as object using the types defined.
getData(id: string, meta?: IMeta): Observable<ISearch>

So the previous calls would change to

getStockData('some id') -> getData('some id')
paginate(1, 3, 'some id', 'some order', 'some attr') ->

const meta: IMeta = {
  pagination: {
    size: 3,
    index: 1
  },
  sorting: {
    order: 'some order',
    attribute: StockMapper.getDataForSorting('some attr')
  }
};

getData('some id', meta);
  1. Check if the optional argument is defined using nullish coalescing operator (??) before using it.
const meta = meta ?? this.service.getSearchMetaDefaults();

Combining everything

getData(id: string, meta?: IMeta): Observable<ISearch> {
  const meta = meta ?? this.service.getSearchMetaDefaults();

  return this.service.search(id, meta).pipe(
    map(response => ({
      searchResult: StockMapper.fromStockResource(response),
      searchCount: response.meta.totalResourceCount
    } as ISearch))
  );
}

Upvotes: 1

Related Questions