Tasteless
Tasteless

Reputation: 54

Proper way of managing model data in Angular 10

Let's say I want to create a simple tic-tac-toe game and i have model for the gameboard. And my question is, where should i put logic for managing this board. For example.

export class Board{
  boardString: string;
  rows: string[];
  separator: string;

  constructor(boardString: string, separator: string = '|'){
    this.boardString = boardString;
    this.separator = separator;
    this.rows = this.boardString.split('|');
  }
}
// inside model class 
atIndex(index: number): string{
    const atCol = index % this.rows.length;
    const atRow = (index - atCol) / this.rows.length;
    return this.rows[atRow][atCol];
  }

isFinished(): boolean {
  // check if game is finished
}

getRow(index): string{
 return this.rows[index]
}

vs

// or in the Service
atIndex(index: number): string{
    const atCol = index % this.boardModel.rows.length;
    const atRow = (index - atCol) / this.boardModel.rows.length;
    return this.boardModel.rows[atRow][atCol];
  }

isFinished(): boolean{
  // check if game is finished
}

getBoardRow(index): string{
  return this.boardModel.rows[index];
}

I don't know if I made myself clear. Tic-tac-toe it's just an example. I want to know where should I put logic responsible for managing model properties? I read from documentation that all logic should be inside services. But for me in some cases it fits more to the model class (e.g., getters). Is it an anti-pattern to keep methods inside model class?

Upvotes: 2

Views: 295

Answers (1)

Jiri Kralovec
Jiri Kralovec

Reputation: 1617

Saying I read from documentation that all logic should be inside services is a bit misleading. Of course it really depends what is the logic doing and it absolutely isn't true that all logic should be in services.

For Models, it would make perfect sense to keep some logic within. A great example would be some Modal or Notification class, which would provide some functionality after initialization like close, onClose, and so on. Imagine you would need to close your notification through a service like notificationService.close(<notificationUniqueId).

You talked about components in your example. The logic you presented is perfectly fine for a component. I would even say it is the best practice to put it into the component - it will make the integration with the UI cleaner and simpler and your code will be more manageable.

I do understand your struggle though. Sometimes it might happen that your UI logic will spread across multiple components. However, I would still stay away from putting it into a Service. Personally, I try to limit services to logic which a) performs some API calls, b) formats data in some way or c) manages state and actions throughout the application. In my recent projects, we implemented another Injectable type which we called CommonUIHandler - this subset of classes handled repetetive logic throughout components. But it created yet another level of abstraction and kept the traditional services from growing when it was not required.

I am sure if you search for Angular design patterns, you will find many valuable resources. An example worth mentioning might be https://coryrylan.com/blog/angular-design-patterns-feature-services

Upvotes: 1

Related Questions