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

440
Visualizações
BehaviorSubject: mutating current value between subscriptions

Assume I have BehaviorSubject with User interface:

interface User {
  firstName: string;
  lastName: string;
}

let user: User = {
  firstName: 'Cuong',
  lastName: 'Le',
};

let bs = new BehaviorSubject<User>(user);

There are two subsciptions, sub1 tried to change the first name. Sub2 subscribes later and user object has first name changed also as the sub1 did change it before:

let sub1 = bs.subscribe((u) => {
  u.firstName = 'An';

  console.log(u);
});

let sub2 = bs.subscribe((u) => {
  console.log(u);
});

it's hard to debug when this case happens in big Angular application. How we make the value immutable when subscribing?

I am looking deep immutable solution to prevent code somewhere else to change the data instead of the shadow one

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

0

Using this answer and wrapping your type in this Immutable utility type should solve your problem. Unlike the readonly keyword or ReadOnly utility type, the Immutable interface in this answer will recursively makes all properties read only.

interface User {
  firstName: string;
  lastName: string;
  address: { 
    street: string;
  } 
}

let user: User = {
  firstName: 'Cuong',
  lastName: 'Le',
  address: { 
    street: '123 Sesame St.'
  }
};

let bs = new BehaviorSubject<Immutable<User>>(user);

let sub1 = bs.subscribe((u) => {
  u.address.street = '456'; //<-- Cannot assign to 'street' because it is a read-only property.
  console.log(u);
});
over 4 years ago · Santiago Trujillo Relatório

0

You can use the utility type Readonly<T> to mark the type on the BehaviorSubject as Readonly<User> instead of User:

let bs = new BehaviorSubject<Readonly<User>>(user);

Now, TS will warn you when you try to modify:

screenshot

Cannot assign to 'firstName' because it is a read-only property. (2540)

over 4 years ago · Santiago Trujillo Relatório

0

This is a problem I've had to solve several times. As long as you are passing simple non-circular objects through the subject this solution should work.

The one requirement is that you utilize the lodash library, which supports a very fast deep copy (no reference copies). I've looked everywhere and I've yet to find one that is faster.

let bs = (new BehaviorSubject<User>(user)).pipe(    
     map((userData) => _.cloneDeep(userData)) 
);

I've used this on fairly large state objects and I've always been impressed by how quickly it is able to perform copies. The implication here is that any emission coming out of the subject is a copy of the original, so changes happen in isolation and will never be able to trail back to the source.

over 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