Angular 4 - clicking a new element on an array from observable

I have a page where I show a list with locations , and click on each of them, I show assets for this location . I created the template as follows:

 <li *ngFor="let location of locations" (click)="select(location)" droppable [dragOverClass]="'drag-target-border'" (onDrop)="onItemDrop($event, location)" > {{ location.name }} <ul *ngIf="currentLocation == location && assetsVisible"> <ng-container *ngIf="currentLocation.assets?.length > 0;else message"> <li *ngFor="let asset of currentLocation.assets" class="asset" draggable [dragData]="asset" > <p>{{ asset.title }}</p> <p>{{ asset.address }}</p> <p>{{ asset.value }}</p> </li> </ng-container> <ng-template #message>No assets for {{ location.name }}</ng-template> </ul> </li> 

And in the component, I set an empty array of assets and an empty currentLocation :

  locations: any[] = []; currentLocation: any = {}; assets: any[] = []; 

And then in the select method I retrieve such assets as follows:

  select(location:any = {){ if (this.currentLocation != location || !this.assetsVisible) { this.assetsVisible = true; } else { this.assetsVisible = false; } this.currentAddress = address; this.locationService.getAssets(location.Id) .subscribe( assets => this.assets = assets ); } 

What I would like to do since I use the drag and drop plugin for Angular . I would like to make it possible to drag assets from one place to another. And then just temporarily push this asset onto the assets array. I made a function for this:

 onItemDrop(e: any, location:any = {}) { this.assets = []; this.assets.push(e.dragData); this.select(location); } 

So, when the user drags and transfers the asset from one place to another, I empty the assets array and click on the new asset that was dragged into the array. But then in the select method, I get all the assets for this new location , which was dropped by the asset , and overwrites the assets array. How can I click on the same array of those assets , so that I have both a new asset and assets the location that I get from the service endpoint? I tried another approach, when I first emptied the assets of the array and then called and passed a new location method and a new asset to select :

 onItemDrop(e: any, location:any = {}) { this.assets = []; this.select(location, e.dragData); } 

And then, in the select method, I set the asset parameter as optional, and then dragged it there into the assets array after I got all the assets for this location from the service

 select(location:any = {}, asset?:any = {}) { this.locationService.getAssets(location.Id) .subscribe( assets => this.assets = assets, if (asset) {this.assets.push(asset)} ); } 

But this did not work, the object that was reset to the new location was not displayed in the template. How can i achieve this?

+5
source share
1 answer

Well in your first approach, you rewrite your assets array in your subscribe function:

 this.locationService.getAssets(location.Id).subscribe( assets => this.assets = assets ); 

So, it is obvious that the asset temporarily stored in this array is lost at this stage.

Your second approach makes more sense, but you are using subscribe incorrectly in this example:

 this.locationService.getAssets(location.Id).subscribe( assets => this.assets = assets, if (asset) {this.assets.push(asset)} ); 

In this case, the if (asset) ... is passed as the second argument to your subscribe call, which is an error callback . You want to do it like this:

 this.locationService.getAssets(location.Id).subscribe( (assets) => { this.assets = assets; if (asset) { this.assets.push(asset) } }); 

Hope this helps.

Update: I'm not even sure that this part of if (asset) ... how you implemented it even works as an error callback. you will probably get an error there if this call is called because a function is expected, not an expression (but, as I said, I'm not sure about that).

+2
source

Source: https://habr.com/ru/post/1268694/


All Articles