Assets

assets(modules) downloads the images a screen should not pop in with. useAssets() is a hook around Asset.loadAsync, which is already a plain promise with no React in it - what is worth having is the reason the hook exists: a screen that shows an image bundled with the app still has to wait for it the first time, and a splash screen or a skeleton is only useful if something says when the wait is over.

Install

npx expo install expo-asset
import { assets } from '@ng-native/expo/assets';

The smallest useful example

import { Component } from '@angular/core';
import { View, Image } from '@ng-native/components';
import { assets } from '@ng-native/expo/assets';

@Component({
  selector: 'app-hero',
  imports: [View, Image],
  template: `
    @if (hero.isLoading()) {
      <view class="bg-slate-200 h-40" />
    } @else if (hero.error() || !hero.value()?.length) {
      <view class="bg-slate-200 h-40" />
    } @else {
      <image [source]="{ uri: hero.value()![0].uri }" />
    }
  `,
})
export class Hero {
  protected readonly hero = assets(() => [require('./hero.png')]);
}

assets(modules, options)

Returns an Angular ResourceRef: value() is undefined until the first load resolves, then the list of downloaded assets, each carrying uri, width and height; isLoading() and error() follow the usual resource shape, and a failed download lands in error() rather than being thrown at a caller who has nothing to do with it.

modules is a reactive function: read a signal inside it and a change re-runs the load, which is what a screen showing one of several pictures wants:

protected readonly photo = assets(() => [this.photos()[this.index()]]);

Called per call site on purpose, for the same reason the hook is: two screens loading different pictures are two separate waits, and one shared "loaded" signal would have the second screen's load answer the first's.

An app that wants assets warmed before there is an injector at all - during bootstrap, say - calls Asset.loadAsync from expo-asset directly; there is nothing here to add for that case.

Without the module installed

The resource resolves to an empty list rather than throwing or rejecting.

Angular components as native iOS and Android views, built and shipped with Expo.

An alpha. MIT licensed. Sponsor its development.

An independent project, not affiliated with or endorsed by Google, the Angular team or Expo. Angular is a trademark of Google LLC.