0

Okay, let met explain. I am getting a obsersable from AngularFire Database, and here is what I pretend to do: - get 2 static copies of the obsersable response - show 1 static copy - allow user to modify this static copy and not save it - when user decides too cancel the changes, i simply get the copy number 2 and set it to copy number 1.

getting obsersable:

this.afoDatabase.object("usuarios/"+this.userKey+"/pacientes/"+this.pacienteKey).map(res=> {
  this.model = res;
  this.model2 = res;
}).first().toPromise();

when the users decides to cancel the changes, here is what i am doing:

this.model = this.model2;
  // this.model is the copy number 1 and this.model2 is the 'unchanged' copy number 2

but when i do it, the copy number 2, even that i never showed or changed it, is exactly equal to copy number 1;

2 Answers2

1

Updated

You can use combineLatest like

let supplier = this.afoDatabase.object("usuarios/" + this.userKey + "/pacientes/" + this.pacienteKey);
Observable.combineLatest(supplier, supplier)
  .map([model1, model2]=> {
    this.model1=model1;
    this.model2=model2;
  }).first()
  ...

CombineLatest will emit an array when both of these observables emits. Here model1 and model2 should have same value.

Note: This will create two separate requests. If you want to create single request then look below at Previous Answer.

Previous Answer

Look here

let res = {foo:1,bar:2}
let model1 = res;
let model2 = res;
model1.foo=3;
console.log(model1.foo) //3
console.log(model2.foo) //3

Because when we declare model1 and model2 with value res, so both points to the same object. Both holds the reference of same object (here res) and changing one changes other.

What you need to do is clone res to model2 so it will a different object with same value as res. Cloning is of two types shallow and deep.

  1. Efficient deep copy
  2. Shallow copy
  3. Difference between shallow and deep copy.

If your res objects values are string, numbers etc then you need shallow copy. Example

res= {a:1,b:"2"}

If they contains array, other objects then you need deep copy. Example

res={a:{c:1},b:[2,3]}
amitdigga
  • 6,550
  • 4
  • 26
  • 31
  • Thank you! Instead of a assign the "res" to the models, i simply assigned a copy of it, using the assign method explained on this link: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign – Guilherme Pereira Mar 23 '18 at 12:09
0

Map is used to modify data received in each event. So you need to assign data to model like

.first((data) => model = data)

Then use

.subscribe((data) => model2 = data)

If you want to modify data format you may call

.map((data) => { let res = modifyData(data); return res});

Update:

import { timer } from 'rxjs/observable/timer';
import 'rxjs/add/operator/first';

let model, model1;

let observable = timer(0, 1000);

observable.first().subscribe((n) => { 
  model = n;
});

observable.subscribe((n) => {
  model1 = n;
});
Vayrex
  • 1,417
  • 1
  • 11
  • 13
  • .looks like it is not how use the first() method. Here what it returns:: Argument of type '(data: void) => void' is not assignable to parameter of type '(value: void, index: number, source: Observable) => boolean' – Guilherme Pereira Mar 21 '18 at 13:02