I'm working on an Electron app using Angular, and the main page is supposed to display a list of items which are loaded asynchronously from a JSON file.
They load and animate fine, but in order to stagger their animation, I call angular animate's Query function.
Unfortunately, this query returns zero elements, despite the fact that they successfully load almost immediately, with the correct animation (just not staggered).
I suspect this has something to do with the query firing before the data is loaded, but I'm not sure what I can do to resolve that.
The relevant code is included below.
HTML:
<div [@itemList]="itemService.items.length">
<div class="item-card" *ngFor="let item of itemService.items |
async;">
</div>
</div>
Component:
@Component({
selector: 'app-notes-list',
templateUrl: './notes-list.component.html',
styleUrls: ['./notes-list.component.css'],
animations: [
trigger('items', [
transition(':enter', [
style({ transform: 'scale(0.5)', opacity: 0 }), // initial
animate('1s cubic-bezier(.8, -0.6, 0.2, 1.5)',
style({ transform: 'scale(1)', opacity: 1 })) // final
]),
transition(':leave', [
style({ transform: 'scale(1)', opacity: 1, height: '*' }),
animate('1s cubic-bezier(.8, -0.6, 0.2, 1.5)',
style({
transform: 'scale(0.5)', opacity: 0,
height: '0px', margin: '0px'
}))
])
]),
trigger('itemList', [
transition(':enter', [
query('.item-card', stagger(3000, animateChild()))
]),
])
]
})
export class NotesListComponent implements OnInit {
constructor(private itemService: ItemService) { }
ngOnInit() {
this.getItems();
}
getItems(): void {
this.itemService.getItems();
}
}
Service:
@Injectable()
export class ItemService {
items: Subject<Item[]>;
itemDataStore: Item[];
constructor(private electronService: ElectronService,
private zone: NgZone) {
this.items = new Subject<Item[]>();
this.electronService.ipcRenderer.on('sending-items', (event, args) => {
this.itemDataStore = args;
this.zone.run(() => {
console.log('Got data');
this.items.next(this.itemDataStore);
});
});
};
getItems(): Observable<Item[]> {
this.electronService.ipcRenderer.send('get-items');
return this.items.asObservable();
}
}
items: Subject<Item[]>;
should be in the component that call the service.
Then you should subscribe to the method returning an Observable, to get the items in the component. It should look close to this :
this.itemService.getItems().subscribe(data => {
this.items = data;
});
Then in component.html
<div [@itemList]="items.length">
<div class="item-card" *ngFor="let item of items |
async;">
</div>
</div>
Update
To solve the issue (length of undefined), set the optional parameter to true, in the query :
trigger('itemList', [
transition(':enter', [
query('.item-card', [
stagger(3000, [
animateChild()
]),
], { optional: true })
]),
])
and in the the div : [@itemList]="items?.length"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With