Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

206
Visualizações
Where to initialise model objects within a redux / ngrx application architecture

Background:

Team is building a large REST-based web application using Angular and the @ngrx library for state management.

We wish to model entities from the server as TypeScript classes. These may be: accounts, users etc

This achieves:

  • Loose coupling to the API; if the response changes, only the model must change
  • Encapsulating basic functionality e.g. string concatenation of first and last name to make fullName

The uncertainty lies in when, during the application's timeline, to initialise the model, calling: new Account(accountResponse).

Conventional logic suggests to do this as early as possible, in a service along side the logic to retrieve the accounts (be it from a cache, server response, etc).

this.apiService.fetch(AccountService.URL)
      .map(accounts => accounts.map((a: AccountResponse) => new Account(a)));

This method is invoked by an ngrx effect, then following a successful response, the Account objects are added to the store by the reducer.

This works, however... ngrx / redux "best practice" states only plain objects and primitives should be kept in the store, for ease of serialisation among other reasons.

To adhere to this advice, initialising the Account object must happen much further down the line. Either in individual components, in a state selector, or generally wherever an account is used.

This doesn't make sense to me, as the raw account response objects are being passed around the application, somewhat defeating the point of wrapping them in a model in the first place.

The application is structurally similar to @ngrx/example book app which, given its simplicity, does not wrap the server responses in model objects.


Questions:

  • What are the detrimental effects of keeping initialised classes in the store (besides serialisability)?

  • If only plain objects are to be kept in the store, where in the flow of data through the app are model classes best initialised?

about 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

The easiest way to work with ngrx is to see it like a database, not just a javascript shared object cache. You would not store javascript helpers in the database, same for ngrx.

You can either stop using model functions and instead use utility methods when needed, or you can wrap the selector results using an observable operator. Something like state.pipe(select(mySelector), myWrapFunction) though you will end up re-creating your wrapper every time.

You might want to look at the viewmodel design pattern (e.g. [MVVM] (https://en.m.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel)) to see approaches similar to what you are trying to do.

about 4 years ago · Santiago Trujillo Relatório

0

Check this example on how to initialize the state of a feature in the ngrx store. I hope this is what you are looking for.

about 4 years ago · Santiago Trujillo Relatório

0

@kyranjamie I'm trying to understand how to do in best-practice way. Did I understand you correct? You store a plain object in a state. When a component needs the object from the state it uses a service, for example: HomeService - to get HomeModel object instead of a plain object

@Injectable({
  providedIn: 'root'
})
export class HomeService {

  constructor() {
  }

  public getSelectedHome(homeObject: HomeJSON) {
    return Object.assign(new HomeModel(), homeObject);
  }
}

A component needs to subscribe to the state. It's subscribed to a change in the state, but instead of using directly the state plain object, it uses HomeService to make the plain object into a class object(HomeModel).

ngOnInit() {
    this.store.pipe(select(getSelectedHome)).subscribe(
      home => {
        this.home = this.homeService.getSelectedHome(home);
      }
    );
  }

Is this how you do it?

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda