Search code examples
javascriptangulartypescriptangular-gridster2

How to fix the angular gridster appending data


here's the code:

app.component.html

<input type="text" [(ngModel)]="newAreaName"/><button (click)="addItem()" [disabled]="editing ? false : true">ADD</button>
<button (click)="toggleEditing()">{{ editing ? 'Cancel' : 'Edit'}}</button>
<app-line (layout)="setFloorLayout($event)" [editing]="editing" [newAreaName]="newArea"></app-line>

app.component.ts

flrLayout = [];
  editing = true;

  newAreaName = "";
  newArea = "";

  setFloorLayout(data: any) {
    this.flrLayout = data;
  }

  addItem(): void {
this.newArea = this.newAreaName;
this.newAreaName = "";
console.log(`SUCCESS ADDING`);
  }
  toggleEditing() {
    this.editing = !this.editing;
  }

child component line.component.ts

@Input() newAreaName: string;
  @Output() layout: EventEmitter<any> = new EventEmitter();
  @Input() editing: any;

  options: Safe;

  dashboard = [];

  ngOnInit() {}

  ngOnChanges() {
    console.log(this.dashboard);
    if (this.newAreaName && this.editing) {
      this.addItem(this.newAreaName);
    }
  }
  addItem(areaName: string): void {
    this.dashboard.push({ x: 0, y: 0, cols: 1, rows: 1, area: areaName });
    this.layout.emit(this.dashboard);
  }

The problem here is after adding new data, when i click the cancel and then when I try to click the edit button it will automatically appending a new data. instead the dashboard array will be empty.

here's the code & output: https://stackblitz.com/edit/angular-rc7bbz?file=src%2Fapp%2Fapp.component.ts

NOTE: after adding data it, click cancel then click the edit button.

Let say there's a existing data

dashboard = [{
area: "Area1"
cols: 1
rows: 1
x: 0
y: 0
}]

then add a "Area2" the data should be like this.

 dashboard = [{
    area: "Area1"
    cols: 1
    rows: 1
    x: 0
    y: 0
    },{
    area: "Area2"
    cols: 1
    rows: 1
    x: 0
    y: 0
    }]

then when it click the cancel button and click the edit button it should be like this:

dashboard = [{
        area: "Area1"
        cols: 1
        rows: 1
        x: 0
        y: 0
        }]

Solution

  • your line.component.ts contain the following line

    
      ngOnChanges() {
        if (this.editing) {
          this.addItem(this.newAreaName);
        }
      }
      addItem(areaName: string): void {
        this.dashboard.push({ x: 0, y: 0, cols: 1, rows: 1, area: areaName });
        this.layout.emit(this.dashboard);
      }
    

    everytime one of the following input

      @Input() newAreaName: string;
      @Input() editing: any;
    

    changes while editing is true, a new item will be pushed.

    It is not a good practice what you are doing, basically, you are creating the element from your component, using a text input change event as trigger. You probably want to change the logic and add the button inside your app-line component (or the addItem outside of that component)

    One quick but a bit ugly solution I could think of mantaining your implementation is using a boolean for trigger =>

    https://stackblitz.com/edit/angular-9geygo?file=src/app/line/line.component.ts