Angular 6 - Using Observable to trigger event between siblings
up vote
0
down vote
favorite
So I have a collection of divs in app-component filled with my app-cube
components, and I have an array filled with GridProp
objects in the parent component which's indexes represents each cell in the collection, meaning I create the content of each "cell" based on the content of array[i].
At array[i] I have an object with an Observable in it among other things like the content for cells. When I update something in cell i
I want to update the siblings of cell [i-1]
and [i+1]
.
I am trying to do this by having each app-cube
subscribe to the observable in the matching object in the array. This way I should be able to simply send a value to the observer in the array at any index and have it trigger the subscribed components subscription handler, right?
The objects in the array are of this class
export class GridProp implements OnInit {
private terrain = new Terrain();
coord: Array<number>;
cont: {};
observer: Observer<string>;
observable: Observable<string> = new Observable((observer: Observer<string>) => {
this.observer = observer;
});
}
Then in the cube-component.ts
@Component({
selector: 'app-cube',
templateUrl: './cube.component.html',
styleUrls: ['./cube.component.css']
})
export class CubeComponent implements OnInit {
@Input() point; // Represents the relevant GridProp object
ngOnInit() {
this.point.observable.subscribe(this.handleCubeUpdate);
}
handleCubeUpdate() {
console.log('handling!');
this.updateWalls();
}
updateWalls() {
// Do stuff to the "walls" values used in this cube.component.html
}
toggleWalls() {
for (const direction in this.point.cont.terrain.walls) {
if (this.getSide(direction) && this.getSide(direction).cont.terrain.isBlock) {
this.point.cont.terrain.walls[direction] = false;
this.getSide(direction).observer.next(true);
} else {
this.point.cont.terrain.walls[direction] = true;
}
}
this.updateWalls();
}
}
In the parent component I distrubte the app-cube
<div class="grid-point-z" *ngFor="let z of y">
<div
class="grid-point"
attr.data-point="{{ z.coord }}"
[ngStyle]="{
'z-index': z.coord[2]
}">
<app-cube
[point]="z"
[coord]="z"
[level]="level"
(click)="clickPoint(z)"
(change)="onCubeChange($event)">
{{z}}
</app-cube>
</div>
</div>
It crashes with the error
ERROR TypeError: this.updateWalls is not a function
at SafeSubscriber.push../src/app/assets/cube/cube.component.ts.CubeComponent.handleCubeUpdate [as _next] (cube.component.ts:71)
So I guess it doesn't recognize this.handleCubeUpdate
in the subscription in CubeComponent. Is there a work-around for this?
angular rxjs
|
show 3 more comments
up vote
0
down vote
favorite
So I have a collection of divs in app-component filled with my app-cube
components, and I have an array filled with GridProp
objects in the parent component which's indexes represents each cell in the collection, meaning I create the content of each "cell" based on the content of array[i].
At array[i] I have an object with an Observable in it among other things like the content for cells. When I update something in cell i
I want to update the siblings of cell [i-1]
and [i+1]
.
I am trying to do this by having each app-cube
subscribe to the observable in the matching object in the array. This way I should be able to simply send a value to the observer in the array at any index and have it trigger the subscribed components subscription handler, right?
The objects in the array are of this class
export class GridProp implements OnInit {
private terrain = new Terrain();
coord: Array<number>;
cont: {};
observer: Observer<string>;
observable: Observable<string> = new Observable((observer: Observer<string>) => {
this.observer = observer;
});
}
Then in the cube-component.ts
@Component({
selector: 'app-cube',
templateUrl: './cube.component.html',
styleUrls: ['./cube.component.css']
})
export class CubeComponent implements OnInit {
@Input() point; // Represents the relevant GridProp object
ngOnInit() {
this.point.observable.subscribe(this.handleCubeUpdate);
}
handleCubeUpdate() {
console.log('handling!');
this.updateWalls();
}
updateWalls() {
// Do stuff to the "walls" values used in this cube.component.html
}
toggleWalls() {
for (const direction in this.point.cont.terrain.walls) {
if (this.getSide(direction) && this.getSide(direction).cont.terrain.isBlock) {
this.point.cont.terrain.walls[direction] = false;
this.getSide(direction).observer.next(true);
} else {
this.point.cont.terrain.walls[direction] = true;
}
}
this.updateWalls();
}
}
In the parent component I distrubte the app-cube
<div class="grid-point-z" *ngFor="let z of y">
<div
class="grid-point"
attr.data-point="{{ z.coord }}"
[ngStyle]="{
'z-index': z.coord[2]
}">
<app-cube
[point]="z"
[coord]="z"
[level]="level"
(click)="clickPoint(z)"
(change)="onCubeChange($event)">
{{z}}
</app-cube>
</div>
</div>
It crashes with the error
ERROR TypeError: this.updateWalls is not a function
at SafeSubscriber.push../src/app/assets/cube/cube.component.ts.CubeComponent.handleCubeUpdate [as _next] (cube.component.ts:71)
So I guess it doesn't recognize this.handleCubeUpdate
in the subscription in CubeComponent. Is there a work-around for this?
angular rxjs
1
is that a functionupdateWalls
? it seems to me thathandleCubeUpdate
is being called but look likehandleCubeUpdate
was callingupdateWall
. Also, IMO, I'd useSubject
in yourGridProp
component. ``` private subject = new Subject<string>(); observable: Observable<string> = subject.asObservable(); ```
– dK-
Nov 15 at 12:38
Wops, thank you. I edited in the updateWalls function call. It is inside the handleCubeUpdate function. I changed the code as you described but the issue is the same. handleCubeUpdate is able to console.log "handling!", but the this.updateWalls(); is "is not a function" in the crash log
– NachoDawg
Nov 15 at 12:47
Where the updateWalls is declared ? And as @dK say, it is better to use Subject or BehaviorSubject.
– User.Anonymous
Nov 15 at 12:47
And observable.subscribe declare the object which you subscribe observable.subscribe(p => console.log(p); }. And without next, your observable is useless.
– User.Anonymous
Nov 15 at 12:51
The updateWalls is declared in cube.component.ts. It handles valued used in the HTML file. The .next() is also called later in the cube.component.ts, i'll add it to the post for clarity
– NachoDawg
Nov 15 at 12:52
|
show 3 more comments
up vote
0
down vote
favorite
up vote
0
down vote
favorite
So I have a collection of divs in app-component filled with my app-cube
components, and I have an array filled with GridProp
objects in the parent component which's indexes represents each cell in the collection, meaning I create the content of each "cell" based on the content of array[i].
At array[i] I have an object with an Observable in it among other things like the content for cells. When I update something in cell i
I want to update the siblings of cell [i-1]
and [i+1]
.
I am trying to do this by having each app-cube
subscribe to the observable in the matching object in the array. This way I should be able to simply send a value to the observer in the array at any index and have it trigger the subscribed components subscription handler, right?
The objects in the array are of this class
export class GridProp implements OnInit {
private terrain = new Terrain();
coord: Array<number>;
cont: {};
observer: Observer<string>;
observable: Observable<string> = new Observable((observer: Observer<string>) => {
this.observer = observer;
});
}
Then in the cube-component.ts
@Component({
selector: 'app-cube',
templateUrl: './cube.component.html',
styleUrls: ['./cube.component.css']
})
export class CubeComponent implements OnInit {
@Input() point; // Represents the relevant GridProp object
ngOnInit() {
this.point.observable.subscribe(this.handleCubeUpdate);
}
handleCubeUpdate() {
console.log('handling!');
this.updateWalls();
}
updateWalls() {
// Do stuff to the "walls" values used in this cube.component.html
}
toggleWalls() {
for (const direction in this.point.cont.terrain.walls) {
if (this.getSide(direction) && this.getSide(direction).cont.terrain.isBlock) {
this.point.cont.terrain.walls[direction] = false;
this.getSide(direction).observer.next(true);
} else {
this.point.cont.terrain.walls[direction] = true;
}
}
this.updateWalls();
}
}
In the parent component I distrubte the app-cube
<div class="grid-point-z" *ngFor="let z of y">
<div
class="grid-point"
attr.data-point="{{ z.coord }}"
[ngStyle]="{
'z-index': z.coord[2]
}">
<app-cube
[point]="z"
[coord]="z"
[level]="level"
(click)="clickPoint(z)"
(change)="onCubeChange($event)">
{{z}}
</app-cube>
</div>
</div>
It crashes with the error
ERROR TypeError: this.updateWalls is not a function
at SafeSubscriber.push../src/app/assets/cube/cube.component.ts.CubeComponent.handleCubeUpdate [as _next] (cube.component.ts:71)
So I guess it doesn't recognize this.handleCubeUpdate
in the subscription in CubeComponent. Is there a work-around for this?
angular rxjs
So I have a collection of divs in app-component filled with my app-cube
components, and I have an array filled with GridProp
objects in the parent component which's indexes represents each cell in the collection, meaning I create the content of each "cell" based on the content of array[i].
At array[i] I have an object with an Observable in it among other things like the content for cells. When I update something in cell i
I want to update the siblings of cell [i-1]
and [i+1]
.
I am trying to do this by having each app-cube
subscribe to the observable in the matching object in the array. This way I should be able to simply send a value to the observer in the array at any index and have it trigger the subscribed components subscription handler, right?
The objects in the array are of this class
export class GridProp implements OnInit {
private terrain = new Terrain();
coord: Array<number>;
cont: {};
observer: Observer<string>;
observable: Observable<string> = new Observable((observer: Observer<string>) => {
this.observer = observer;
});
}
Then in the cube-component.ts
@Component({
selector: 'app-cube',
templateUrl: './cube.component.html',
styleUrls: ['./cube.component.css']
})
export class CubeComponent implements OnInit {
@Input() point; // Represents the relevant GridProp object
ngOnInit() {
this.point.observable.subscribe(this.handleCubeUpdate);
}
handleCubeUpdate() {
console.log('handling!');
this.updateWalls();
}
updateWalls() {
// Do stuff to the "walls" values used in this cube.component.html
}
toggleWalls() {
for (const direction in this.point.cont.terrain.walls) {
if (this.getSide(direction) && this.getSide(direction).cont.terrain.isBlock) {
this.point.cont.terrain.walls[direction] = false;
this.getSide(direction).observer.next(true);
} else {
this.point.cont.terrain.walls[direction] = true;
}
}
this.updateWalls();
}
}
In the parent component I distrubte the app-cube
<div class="grid-point-z" *ngFor="let z of y">
<div
class="grid-point"
attr.data-point="{{ z.coord }}"
[ngStyle]="{
'z-index': z.coord[2]
}">
<app-cube
[point]="z"
[coord]="z"
[level]="level"
(click)="clickPoint(z)"
(change)="onCubeChange($event)">
{{z}}
</app-cube>
</div>
</div>
It crashes with the error
ERROR TypeError: this.updateWalls is not a function
at SafeSubscriber.push../src/app/assets/cube/cube.component.ts.CubeComponent.handleCubeUpdate [as _next] (cube.component.ts:71)
So I guess it doesn't recognize this.handleCubeUpdate
in the subscription in CubeComponent. Is there a work-around for this?
angular rxjs
angular rxjs
edited Nov 15 at 12:54
Pac0
7,35922544
7,35922544
asked Nov 15 at 11:57
NachoDawg
1,306717
1,306717
1
is that a functionupdateWalls
? it seems to me thathandleCubeUpdate
is being called but look likehandleCubeUpdate
was callingupdateWall
. Also, IMO, I'd useSubject
in yourGridProp
component. ``` private subject = new Subject<string>(); observable: Observable<string> = subject.asObservable(); ```
– dK-
Nov 15 at 12:38
Wops, thank you. I edited in the updateWalls function call. It is inside the handleCubeUpdate function. I changed the code as you described but the issue is the same. handleCubeUpdate is able to console.log "handling!", but the this.updateWalls(); is "is not a function" in the crash log
– NachoDawg
Nov 15 at 12:47
Where the updateWalls is declared ? And as @dK say, it is better to use Subject or BehaviorSubject.
– User.Anonymous
Nov 15 at 12:47
And observable.subscribe declare the object which you subscribe observable.subscribe(p => console.log(p); }. And without next, your observable is useless.
– User.Anonymous
Nov 15 at 12:51
The updateWalls is declared in cube.component.ts. It handles valued used in the HTML file. The .next() is also called later in the cube.component.ts, i'll add it to the post for clarity
– NachoDawg
Nov 15 at 12:52
|
show 3 more comments
1
is that a functionupdateWalls
? it seems to me thathandleCubeUpdate
is being called but look likehandleCubeUpdate
was callingupdateWall
. Also, IMO, I'd useSubject
in yourGridProp
component. ``` private subject = new Subject<string>(); observable: Observable<string> = subject.asObservable(); ```
– dK-
Nov 15 at 12:38
Wops, thank you. I edited in the updateWalls function call. It is inside the handleCubeUpdate function. I changed the code as you described but the issue is the same. handleCubeUpdate is able to console.log "handling!", but the this.updateWalls(); is "is not a function" in the crash log
– NachoDawg
Nov 15 at 12:47
Where the updateWalls is declared ? And as @dK say, it is better to use Subject or BehaviorSubject.
– User.Anonymous
Nov 15 at 12:47
And observable.subscribe declare the object which you subscribe observable.subscribe(p => console.log(p); }. And without next, your observable is useless.
– User.Anonymous
Nov 15 at 12:51
The updateWalls is declared in cube.component.ts. It handles valued used in the HTML file. The .next() is also called later in the cube.component.ts, i'll add it to the post for clarity
– NachoDawg
Nov 15 at 12:52
1
1
is that a function
updateWalls
? it seems to me that handleCubeUpdate
is being called but look like handleCubeUpdate
was calling updateWall
. Also, IMO, I'd use Subject
in your GridProp
component. ``` private subject = new Subject<string>(); observable: Observable<string> = subject.asObservable(); ```– dK-
Nov 15 at 12:38
is that a function
updateWalls
? it seems to me that handleCubeUpdate
is being called but look like handleCubeUpdate
was calling updateWall
. Also, IMO, I'd use Subject
in your GridProp
component. ``` private subject = new Subject<string>(); observable: Observable<string> = subject.asObservable(); ```– dK-
Nov 15 at 12:38
Wops, thank you. I edited in the updateWalls function call. It is inside the handleCubeUpdate function. I changed the code as you described but the issue is the same. handleCubeUpdate is able to console.log "handling!", but the this.updateWalls(); is "is not a function" in the crash log
– NachoDawg
Nov 15 at 12:47
Wops, thank you. I edited in the updateWalls function call. It is inside the handleCubeUpdate function. I changed the code as you described but the issue is the same. handleCubeUpdate is able to console.log "handling!", but the this.updateWalls(); is "is not a function" in the crash log
– NachoDawg
Nov 15 at 12:47
Where the updateWalls is declared ? And as @dK say, it is better to use Subject or BehaviorSubject.
– User.Anonymous
Nov 15 at 12:47
Where the updateWalls is declared ? And as @dK say, it is better to use Subject or BehaviorSubject.
– User.Anonymous
Nov 15 at 12:47
And observable.subscribe declare the object which you subscribe observable.subscribe(p => console.log(p); }. And without next, your observable is useless.
– User.Anonymous
Nov 15 at 12:51
And observable.subscribe declare the object which you subscribe observable.subscribe(p => console.log(p); }. And without next, your observable is useless.
– User.Anonymous
Nov 15 at 12:51
The updateWalls is declared in cube.component.ts. It handles valued used in the HTML file. The .next() is also called later in the cube.component.ts, i'll add it to the post for clarity
– NachoDawg
Nov 15 at 12:52
The updateWalls is declared in cube.component.ts. It handles valued used in the HTML file. The .next() is also called later in the cube.component.ts, i'll add it to the post for clarity
– NachoDawg
Nov 15 at 12:52
|
show 3 more comments
3 Answers
3
active
oldest
votes
up vote
1
down vote
accepted
From my point of view here we have kind of design problem.
In Angular, components can interact with each other using their @Input()
and @Output()
properties(Input - to be aware about changes from parent component and update view, Output - to notify others about changes inside).
So better to add to your CubeComponent
output event somethingChanged
and emit this event when, as you said, you update something.
export class CubeComponent implements OnInit {
@Input() point; // Represents the relevant GridProp object
@Output() somethingChanged = new EventEmitter<GridProp>();
ngOnInit() {
}
notifyOthersComponentAboutUpdate() {
let id = this.point; // You can emit point or some id, to identify it later in parent component
this.somethingChanged.emit(id);
}
}
In you parent component(app-component
) which contains array of app-cube
components create a method updateSiblings(idOfComponentWhichWasUpdated)
and call it from app-cube
component
<div class="grid-point-z" *ngFor="let z of y">
<div
class="grid-point"
attr.data-point="{{ z.coord }}"
[ngStyle]="{
'z-index': z.coord[2]
}">
<app-cube
[point]="z"
[coord]="z"
[level]="level"
(somethingChanged)="updateSiblings($event)">
{{z}}
</app-cube>
</div>
</div>
And in that updateSiblings
method your have access to your y
array(*ngFor="let z of y"
) which contains all data for app-cube
components(y: GridProp
).
You have id of component which was updated, so you can find it in array y
and you can find his siblings and update their data as well. Angular will automatically detect changes in that y
array and your siblings will be updated on UI level.
I ended up using your solution. I kept an observable in the GridProp where i manage the rendering of the "walls", and used the parent component to trigger the observable of any sibling of a clicked point including 'this' point, leaving each context intact. Thanks!
– NachoDawg
Nov 15 at 14:53
Nice to hear that. Happy to help @NachoDawg
– Yury Polubinsky
Nov 15 at 15:10
add a comment |
up vote
2
down vote
Now it make more sense to me that I could try to answer it here.
Hopefully I could articulate this
properly :).
So, when you pass in a function reference in your subscribe
, this
in handleCubeUpdate
has a different context.
You can change your function implementation to arrow function.
handleCubeUpdate = () => {
this.updateWalls();
}
additionally, if your updateWalls
is calling another function, then you should change that updateWalls
function arrow function.
Accepted answer. This allows me to reach the siblings by triggering their corresponding observables like i wanted to, thanks.
– NachoDawg
Nov 15 at 13:13
Actually it doesn't entirely work like i thought. While I manage to trigger the observable of a sibling, 'this' refers to the original point. I changed all the functions touched by handleCubeUpdate to arrow functions, but they always seem to refer to the point that triggered the sibling to update the walls
– NachoDawg
Nov 15 at 14:04
add a comment |
up vote
0
down vote
Have you considered using a REDUX architecture in Angular?
Here's a good tutorial on how it works and the benefits. I have used the exact same tutorial to learn about it and implement.
You could then keep that array in your store and dispatch actions to change thing. Each action could contain the logic to update itself + the two items surrounding it.
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
From my point of view here we have kind of design problem.
In Angular, components can interact with each other using their @Input()
and @Output()
properties(Input - to be aware about changes from parent component and update view, Output - to notify others about changes inside).
So better to add to your CubeComponent
output event somethingChanged
and emit this event when, as you said, you update something.
export class CubeComponent implements OnInit {
@Input() point; // Represents the relevant GridProp object
@Output() somethingChanged = new EventEmitter<GridProp>();
ngOnInit() {
}
notifyOthersComponentAboutUpdate() {
let id = this.point; // You can emit point or some id, to identify it later in parent component
this.somethingChanged.emit(id);
}
}
In you parent component(app-component
) which contains array of app-cube
components create a method updateSiblings(idOfComponentWhichWasUpdated)
and call it from app-cube
component
<div class="grid-point-z" *ngFor="let z of y">
<div
class="grid-point"
attr.data-point="{{ z.coord }}"
[ngStyle]="{
'z-index': z.coord[2]
}">
<app-cube
[point]="z"
[coord]="z"
[level]="level"
(somethingChanged)="updateSiblings($event)">
{{z}}
</app-cube>
</div>
</div>
And in that updateSiblings
method your have access to your y
array(*ngFor="let z of y"
) which contains all data for app-cube
components(y: GridProp
).
You have id of component which was updated, so you can find it in array y
and you can find his siblings and update their data as well. Angular will automatically detect changes in that y
array and your siblings will be updated on UI level.
I ended up using your solution. I kept an observable in the GridProp where i manage the rendering of the "walls", and used the parent component to trigger the observable of any sibling of a clicked point including 'this' point, leaving each context intact. Thanks!
– NachoDawg
Nov 15 at 14:53
Nice to hear that. Happy to help @NachoDawg
– Yury Polubinsky
Nov 15 at 15:10
add a comment |
up vote
1
down vote
accepted
From my point of view here we have kind of design problem.
In Angular, components can interact with each other using their @Input()
and @Output()
properties(Input - to be aware about changes from parent component and update view, Output - to notify others about changes inside).
So better to add to your CubeComponent
output event somethingChanged
and emit this event when, as you said, you update something.
export class CubeComponent implements OnInit {
@Input() point; // Represents the relevant GridProp object
@Output() somethingChanged = new EventEmitter<GridProp>();
ngOnInit() {
}
notifyOthersComponentAboutUpdate() {
let id = this.point; // You can emit point or some id, to identify it later in parent component
this.somethingChanged.emit(id);
}
}
In you parent component(app-component
) which contains array of app-cube
components create a method updateSiblings(idOfComponentWhichWasUpdated)
and call it from app-cube
component
<div class="grid-point-z" *ngFor="let z of y">
<div
class="grid-point"
attr.data-point="{{ z.coord }}"
[ngStyle]="{
'z-index': z.coord[2]
}">
<app-cube
[point]="z"
[coord]="z"
[level]="level"
(somethingChanged)="updateSiblings($event)">
{{z}}
</app-cube>
</div>
</div>
And in that updateSiblings
method your have access to your y
array(*ngFor="let z of y"
) which contains all data for app-cube
components(y: GridProp
).
You have id of component which was updated, so you can find it in array y
and you can find his siblings and update their data as well. Angular will automatically detect changes in that y
array and your siblings will be updated on UI level.
I ended up using your solution. I kept an observable in the GridProp where i manage the rendering of the "walls", and used the parent component to trigger the observable of any sibling of a clicked point including 'this' point, leaving each context intact. Thanks!
– NachoDawg
Nov 15 at 14:53
Nice to hear that. Happy to help @NachoDawg
– Yury Polubinsky
Nov 15 at 15:10
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
From my point of view here we have kind of design problem.
In Angular, components can interact with each other using their @Input()
and @Output()
properties(Input - to be aware about changes from parent component and update view, Output - to notify others about changes inside).
So better to add to your CubeComponent
output event somethingChanged
and emit this event when, as you said, you update something.
export class CubeComponent implements OnInit {
@Input() point; // Represents the relevant GridProp object
@Output() somethingChanged = new EventEmitter<GridProp>();
ngOnInit() {
}
notifyOthersComponentAboutUpdate() {
let id = this.point; // You can emit point or some id, to identify it later in parent component
this.somethingChanged.emit(id);
}
}
In you parent component(app-component
) which contains array of app-cube
components create a method updateSiblings(idOfComponentWhichWasUpdated)
and call it from app-cube
component
<div class="grid-point-z" *ngFor="let z of y">
<div
class="grid-point"
attr.data-point="{{ z.coord }}"
[ngStyle]="{
'z-index': z.coord[2]
}">
<app-cube
[point]="z"
[coord]="z"
[level]="level"
(somethingChanged)="updateSiblings($event)">
{{z}}
</app-cube>
</div>
</div>
And in that updateSiblings
method your have access to your y
array(*ngFor="let z of y"
) which contains all data for app-cube
components(y: GridProp
).
You have id of component which was updated, so you can find it in array y
and you can find his siblings and update their data as well. Angular will automatically detect changes in that y
array and your siblings will be updated on UI level.
From my point of view here we have kind of design problem.
In Angular, components can interact with each other using their @Input()
and @Output()
properties(Input - to be aware about changes from parent component and update view, Output - to notify others about changes inside).
So better to add to your CubeComponent
output event somethingChanged
and emit this event when, as you said, you update something.
export class CubeComponent implements OnInit {
@Input() point; // Represents the relevant GridProp object
@Output() somethingChanged = new EventEmitter<GridProp>();
ngOnInit() {
}
notifyOthersComponentAboutUpdate() {
let id = this.point; // You can emit point or some id, to identify it later in parent component
this.somethingChanged.emit(id);
}
}
In you parent component(app-component
) which contains array of app-cube
components create a method updateSiblings(idOfComponentWhichWasUpdated)
and call it from app-cube
component
<div class="grid-point-z" *ngFor="let z of y">
<div
class="grid-point"
attr.data-point="{{ z.coord }}"
[ngStyle]="{
'z-index': z.coord[2]
}">
<app-cube
[point]="z"
[coord]="z"
[level]="level"
(somethingChanged)="updateSiblings($event)">
{{z}}
</app-cube>
</div>
</div>
And in that updateSiblings
method your have access to your y
array(*ngFor="let z of y"
) which contains all data for app-cube
components(y: GridProp
).
You have id of component which was updated, so you can find it in array y
and you can find his siblings and update their data as well. Angular will automatically detect changes in that y
array and your siblings will be updated on UI level.
edited Nov 15 at 15:13
answered Nov 15 at 13:31
Yury Polubinsky
908
908
I ended up using your solution. I kept an observable in the GridProp where i manage the rendering of the "walls", and used the parent component to trigger the observable of any sibling of a clicked point including 'this' point, leaving each context intact. Thanks!
– NachoDawg
Nov 15 at 14:53
Nice to hear that. Happy to help @NachoDawg
– Yury Polubinsky
Nov 15 at 15:10
add a comment |
I ended up using your solution. I kept an observable in the GridProp where i manage the rendering of the "walls", and used the parent component to trigger the observable of any sibling of a clicked point including 'this' point, leaving each context intact. Thanks!
– NachoDawg
Nov 15 at 14:53
Nice to hear that. Happy to help @NachoDawg
– Yury Polubinsky
Nov 15 at 15:10
I ended up using your solution. I kept an observable in the GridProp where i manage the rendering of the "walls", and used the parent component to trigger the observable of any sibling of a clicked point including 'this' point, leaving each context intact. Thanks!
– NachoDawg
Nov 15 at 14:53
I ended up using your solution. I kept an observable in the GridProp where i manage the rendering of the "walls", and used the parent component to trigger the observable of any sibling of a clicked point including 'this' point, leaving each context intact. Thanks!
– NachoDawg
Nov 15 at 14:53
Nice to hear that. Happy to help @NachoDawg
– Yury Polubinsky
Nov 15 at 15:10
Nice to hear that. Happy to help @NachoDawg
– Yury Polubinsky
Nov 15 at 15:10
add a comment |
up vote
2
down vote
Now it make more sense to me that I could try to answer it here.
Hopefully I could articulate this
properly :).
So, when you pass in a function reference in your subscribe
, this
in handleCubeUpdate
has a different context.
You can change your function implementation to arrow function.
handleCubeUpdate = () => {
this.updateWalls();
}
additionally, if your updateWalls
is calling another function, then you should change that updateWalls
function arrow function.
Accepted answer. This allows me to reach the siblings by triggering their corresponding observables like i wanted to, thanks.
– NachoDawg
Nov 15 at 13:13
Actually it doesn't entirely work like i thought. While I manage to trigger the observable of a sibling, 'this' refers to the original point. I changed all the functions touched by handleCubeUpdate to arrow functions, but they always seem to refer to the point that triggered the sibling to update the walls
– NachoDawg
Nov 15 at 14:04
add a comment |
up vote
2
down vote
Now it make more sense to me that I could try to answer it here.
Hopefully I could articulate this
properly :).
So, when you pass in a function reference in your subscribe
, this
in handleCubeUpdate
has a different context.
You can change your function implementation to arrow function.
handleCubeUpdate = () => {
this.updateWalls();
}
additionally, if your updateWalls
is calling another function, then you should change that updateWalls
function arrow function.
Accepted answer. This allows me to reach the siblings by triggering their corresponding observables like i wanted to, thanks.
– NachoDawg
Nov 15 at 13:13
Actually it doesn't entirely work like i thought. While I manage to trigger the observable of a sibling, 'this' refers to the original point. I changed all the functions touched by handleCubeUpdate to arrow functions, but they always seem to refer to the point that triggered the sibling to update the walls
– NachoDawg
Nov 15 at 14:04
add a comment |
up vote
2
down vote
up vote
2
down vote
Now it make more sense to me that I could try to answer it here.
Hopefully I could articulate this
properly :).
So, when you pass in a function reference in your subscribe
, this
in handleCubeUpdate
has a different context.
You can change your function implementation to arrow function.
handleCubeUpdate = () => {
this.updateWalls();
}
additionally, if your updateWalls
is calling another function, then you should change that updateWalls
function arrow function.
Now it make more sense to me that I could try to answer it here.
Hopefully I could articulate this
properly :).
So, when you pass in a function reference in your subscribe
, this
in handleCubeUpdate
has a different context.
You can change your function implementation to arrow function.
handleCubeUpdate = () => {
this.updateWalls();
}
additionally, if your updateWalls
is calling another function, then you should change that updateWalls
function arrow function.
answered Nov 15 at 13:07
dK-
22828
22828
Accepted answer. This allows me to reach the siblings by triggering their corresponding observables like i wanted to, thanks.
– NachoDawg
Nov 15 at 13:13
Actually it doesn't entirely work like i thought. While I manage to trigger the observable of a sibling, 'this' refers to the original point. I changed all the functions touched by handleCubeUpdate to arrow functions, but they always seem to refer to the point that triggered the sibling to update the walls
– NachoDawg
Nov 15 at 14:04
add a comment |
Accepted answer. This allows me to reach the siblings by triggering their corresponding observables like i wanted to, thanks.
– NachoDawg
Nov 15 at 13:13
Actually it doesn't entirely work like i thought. While I manage to trigger the observable of a sibling, 'this' refers to the original point. I changed all the functions touched by handleCubeUpdate to arrow functions, but they always seem to refer to the point that triggered the sibling to update the walls
– NachoDawg
Nov 15 at 14:04
Accepted answer. This allows me to reach the siblings by triggering their corresponding observables like i wanted to, thanks.
– NachoDawg
Nov 15 at 13:13
Accepted answer. This allows me to reach the siblings by triggering their corresponding observables like i wanted to, thanks.
– NachoDawg
Nov 15 at 13:13
Actually it doesn't entirely work like i thought. While I manage to trigger the observable of a sibling, 'this' refers to the original point. I changed all the functions touched by handleCubeUpdate to arrow functions, but they always seem to refer to the point that triggered the sibling to update the walls
– NachoDawg
Nov 15 at 14:04
Actually it doesn't entirely work like i thought. While I manage to trigger the observable of a sibling, 'this' refers to the original point. I changed all the functions touched by handleCubeUpdate to arrow functions, but they always seem to refer to the point that triggered the sibling to update the walls
– NachoDawg
Nov 15 at 14:04
add a comment |
up vote
0
down vote
Have you considered using a REDUX architecture in Angular?
Here's a good tutorial on how it works and the benefits. I have used the exact same tutorial to learn about it and implement.
You could then keep that array in your store and dispatch actions to change thing. Each action could contain the logic to update itself + the two items surrounding it.
add a comment |
up vote
0
down vote
Have you considered using a REDUX architecture in Angular?
Here's a good tutorial on how it works and the benefits. I have used the exact same tutorial to learn about it and implement.
You could then keep that array in your store and dispatch actions to change thing. Each action could contain the logic to update itself + the two items surrounding it.
add a comment |
up vote
0
down vote
up vote
0
down vote
Have you considered using a REDUX architecture in Angular?
Here's a good tutorial on how it works and the benefits. I have used the exact same tutorial to learn about it and implement.
You could then keep that array in your store and dispatch actions to change thing. Each action could contain the logic to update itself + the two items surrounding it.
Have you considered using a REDUX architecture in Angular?
Here's a good tutorial on how it works and the benefits. I have used the exact same tutorial to learn about it and implement.
You could then keep that array in your store and dispatch actions to change thing. Each action could contain the logic to update itself + the two items surrounding it.
answered Nov 15 at 13:11
SebastianG
748115
748115
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53319005%2fangular-6-using-observable-to-trigger-event-between-siblings%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
is that a function
updateWalls
? it seems to me thathandleCubeUpdate
is being called but look likehandleCubeUpdate
was callingupdateWall
. Also, IMO, I'd useSubject
in yourGridProp
component. ``` private subject = new Subject<string>(); observable: Observable<string> = subject.asObservable(); ```– dK-
Nov 15 at 12:38
Wops, thank you. I edited in the updateWalls function call. It is inside the handleCubeUpdate function. I changed the code as you described but the issue is the same. handleCubeUpdate is able to console.log "handling!", but the this.updateWalls(); is "is not a function" in the crash log
– NachoDawg
Nov 15 at 12:47
Where the updateWalls is declared ? And as @dK say, it is better to use Subject or BehaviorSubject.
– User.Anonymous
Nov 15 at 12:47
And observable.subscribe declare the object which you subscribe observable.subscribe(p => console.log(p); }. And without next, your observable is useless.
– User.Anonymous
Nov 15 at 12:51
The updateWalls is declared in cube.component.ts. It handles valued used in the HTML file. The .next() is also called later in the cube.component.ts, i'll add it to the post for clarity
– NachoDawg
Nov 15 at 12:52