ngx-masonry: Order of items not working

I have seen multiple closed issues adressing this problem, but none of them seems to provide a solution. Is the “horizontalOrder” option broken?

I am loading an array of image objects from my database and using it to display the images and some other information.

HTML of the component:

<ngx-masonry [options]="masonryOptions">
    <div ngxMasonryItem class="wall-item" *ngFor="let image of images">
        <app-image-wall-post [username]="image.name" [message]="image.message" [imagePath]="image.path" [timestamp]="image.timestamp"></app-image-wall-post>
    </div>
</ngx-masonry>

The app-image-wall-post component contains a material card with the image in it.

TS of the component:

export class ImageWallComponent implements OnInit {
  images: ImageEntry[];

  public masonryOptions: NgxMasonryOptions = {
    horizontalOrder: true,
    originTop: true,
    originLeft: true,
    itemSelector: '.wall-item',
  };

  constructor(private wallService: WallService, private router: Router, private eventService:EventService) { }

  ngOnInit(): void {
    this.wallService.initImageStream();

    this.wallService.images.subscribe(newImages => {
      this.images = newImages.sort((a,b) => (a.timestamp > b.timestamp) ? -1 : ((b.timestamp > a.timestamp) ? 1 : 0));

      this.images.forEach(image => {
        console.log(new Date(image.timestamp) + ", " + image.name)
      })
    });
  }
}

The sort function in the subscribe callback makes sure that the images are sorted by their upload-timestamp. When checking the console output of the images array, the sorting seems fine. However, the masonry order is somehow random. Each time I refresh the page, the order changes.

Here is also a screenshot of the console output where you can see the properly sorted array, and the images. which are not ordered properly (see the date information on the card): image

Why is that, and what am I doing wrong? When I use a normal flexbox layout, the order is correct.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 16 (8 by maintainers)

Most upvoted comments

@ifumi right, put the items to an array like pendingItems, and use an event from image item <img src="{{imageUrl}}" (load)="loaded.emit()" (error)="loaded.emit()">. When your masonry component gets the loaded event do this.cardItems.push(this.pendingItems.shift());