Image picker
ImagePicker wraps expo-image-picker: the system's own photo library and camera UI, not a view
your app draws. Use it for an avatar, an attachment, anything the person picks or shoots once and
hands over.
Import
import { ImagePicker } from '@ng-native/expo';
Inject
inject(ImagePicker)Install
npx expo install expo-image-pickerimport { ImagePicker, type PickedAsset } from '@ng-native/expo/image-picker';The smallest thing that works
import { Component, inject, signal } from '@angular/core';
import { ImagePicker, type PickedAsset } from '@ng-native/expo/image-picker';
@Component({
selector: 'app-avatar',
template: `
<pressable (press)="choose()"><text>Choose a photo</text></pressable>
<pressable (press)="take()"><text>Take one</text></pressable>
`,
})
export class Avatar {
private readonly picker = inject(ImagePicker);
protected readonly photo = signal<PickedAsset | null>(null);
protected async choose(): Promise<void> {
const [photo] = await this.picker.pick({ mediaTypes: ['images'], allowsEditing: true });
if (photo) this.photo.set(photo);
}
protected async take(): Promise<void> {
const [photo] = await this.picker.capture({ quality: 0.8 });
if (photo) this.photo.set(photo);
}
}Picking and capturing
pick(options)opens the system photo picker. It needs no permission to pick from - the system UI runs outside your app's sandbox - sopick()never asks for one.capture(options)opens the system camera, asking for the camera permission first. Without it, it resolves to an empty list rather than opening the camera.- Both resolve to a list of assets, empty if the person cancelled (or refused the camera),
rather than a result object to unwrap - so a destructured
const [photo] = await picker.pick()givesundefined, not a{ canceled: true }you have to check first. optionsisexpo-image-picker's ownImagePickerOptions, passed straight through:mediaTypes('images','videos','livePhotos'),allowsEditing,quality,allowsMultipleSelectionand the rest.
Permissions
Two separate permissions, each a Permission (see Permissions):
libraryPermissionguards reading the library yourself, outsidepick()- the picker itself needs nothing. Ask for it only if your app browses or uploads from the library directly.cameraPermissionis whatcapture()asks for itself, viaensure(). ReadcameraPermission.blocked()to know when to send the person to Settings instead of asking again.
Add to Info.plist:
<key>NSPhotoLibraryUsageDescription</key>
<string>Allow this app to access your photos</string>
<key>NSCameraUsageDescription</key>
<string>Allow this app to access your camera</string>
<key>NSMicrophoneUsageDescription</key>
<string>Allow this app to access your microphone</string>Android's permissions are added automatically by the module's config plugin.
Without the module
Every method behaves as though the person refused: pick() and capture() resolve to an empty
list, and both permissions report denied with canAskAgain: false rather than throwing.
Reference
ImagePickerservice@ng-native/expoimport { ImagePicker } from '@ng-native/expo';Methods
pick(options?: PickerOptions): Promise<readonly PickedAsset[]>Pick from the photo library. Empty if they cancelled.
capture(options?: PickerOptions): Promise<readonly PickedAsset[]>Take a photo or video with the system camera. Empty if they cancelled or refused it.