Skip to content

DataContainer — API Reference

← Kembali ke Overview | Changelog

Referensi lengkap untuk semua exports di utils-data-container

Versi: 0.4.0


Daftar Isi

Composables

Types


Composables

useDataContainer

Membuat container object untuk mengelola state API-driven list.

Signature:

ts
function useDataContainer<
  TData = unknown,
  TFilter extends Record<string, unknown> = Record<string, unknown>,
  TAdditional = unknown,
>(
  initialFilter?: TFilter,
  queryIntent?: QueryIntent
): DataContainerObject<TData, TFilter, TAdditional>

Parameters

NameTypeDefaultDescription
initialFilterTFilter{}Nilai awal filter
queryIntentQueryIntent-Initialize state dari URL/router Lihat selengkapnya

queryIntent

Pre-populate state pagination, sort, dan search saat composable diinisialisasi.

Structure:

ts
{
  pagination?: {
    mode: 'none' | 'lengthAware' | 'regular' | 'simple' | 'cursor';
    perPage?: number;
    page?: number;  // untuk mode lengthAware/regular/simple
  };
  sort?: { by: string; dir?: 'asc' | 'desc' };
  search?: { param?: string; value?: string };
}

'regular' adalah alias dari 'lengthAware'. Menyediakan pagination akan set page.setup saat konstruksi.

Returns

Contains:


Reactive State

data
ts
data: Ref<TData[]>

Array data dari API response. Di-populate oleh mapFromResponse().

⚠️ Penting — Penggunaan .value:

  • Di <script>: Perlu .valuecontainer.data.value
  • Di <template>: Tidak perlu .value (auto-unwrap) → container.data

filter
ts
filter: Reactive<TFilter>

Draft filter state — ini yang user edit langsung. Tidak mempengaruhi URL params sampai applyFilter() dipanggil.


page
ts
page: PageConfig

Reactive pagination state, akses langsung tanpa .value. Baca page.setup?.mode, page.numeric.current, page.cursor.next, dll. Gunakan declarePagination() untuk set mode dan navigatePage() / nextPage() / prevPage() untuk navigasi.


sort
ts
sort: SortConfig

Reactive sort state, akses langsung. Baca sort.sortBy dan sort.sortDir langsung. Gunakan sort methods untuk update.


error
ts
error: Ref<ErrorInfo | null>

Error info dari API. Di-set otomatis oleh mapFromResponse() saat response.success === false.


additionalData
ts
additionalData: Ref<TAdditional | null>

Data tambahan dari field appended di API response.


loadStatus
ts
loadStatus: -1 | 0 | 1  // getter/setter, bukan Ref

Status loading: 0 = loading, 1 = loaded, -1 = error. Set ke 0 sebelum fetch; mapFromResponse() otomatis set ke 1 atau -1.


ts
search: string  // getter/setter, bukan Ref

Nilai search saat ini. Bind ke input dengan v-model="container.search". Gunakan submitSearch() (bukan set langsung) untuk trigger search baru dengan page reset.


_appliedFilter
ts
_appliedFilter: TFilter  // snapshot clone, read-only

Snapshot clone dari applied filter — bukan reactive object. Tidak mutasi langsung.


_searchConfig
ts
_searchConfig: SearchConfig  // snapshot, read-only

Snapshot konfigurasi search internal.


Computed Properties

isLoading
ts
isLoading: ComputedRef<boolean>

true saat loadStatus === 0.


isLoaded
ts
isLoaded: ComputedRef<boolean>

true saat loadStatus === 1.


hasError
ts
hasError: ComputedRef<boolean>

true saat loadStatus === -1 atau error tidak null.


isEmpty
ts
isEmpty: ComputedRef<boolean>

true saat data.length === 0.


Data Methods

appendData()
ts
appendData(item: TData): void

Tambahkan item ke data secara lokal tanpa re-fetch (optimistic update).


deleteDataByIndex()
ts
deleteDataByIndex(index: number): boolean

Hapus item di index tertentu. Mengembalikan true jika berhasil, false jika index out of bounds.


getDataLength()
ts
getDataLength(): number

Jumlah item dalam data.


Filter Methods

setFilter()
ts
setFilter(path: string, value: unknown): void

Set nilai satu field filter via dot-notation path, termasuk nested.

Contoh:

ts
container.setFilter('status', 'active');
container.setFilter('user.role', 'admin'); // nested

Perbedaan dengan modifyFilter(): setFilter menarget satu field via string path (termasuk nested). modifyFilter menerima partial object untuk update beberapa top-level key sekaligus.


modifyFilter()
ts
modifyFilter(partial: Partial<TFilter>): void

Merge partial filter ke draft. Hanya key yang disertakan yang berubah; key lain tidak disentuh.

Contoh:

ts
container.modifyFilter({ category: 'laptop', status: 'active' });

applyFilter()
ts
applyFilter(): void

Promote draft filter ke _appliedFilter setelah strip nilai kosong/null. Wajib dipanggil sebelum fetch agar perubahan filter masuk ke URL params.


resetFilterToInit()
ts
resetFilterToInit(paths?: string | string[]): void

Reset draft filter ke nilai initialFilter. Jika paths di-pass, hanya field tersebut yang di-reset.


resetFilterToApplied()
ts
resetFilterToApplied(paths?: string | string[]): void

Reset draft filter ke _appliedFilter (batalkan perubahan yang belum di-apply).


hasUnappliedFilterChanges()
ts
hasUnappliedFilterChanges(): boolean

true jika draft filter berbeda dari _appliedFilter.


isUsingFilter()
ts
isUsingFilter(): boolean

true jika _appliedFilter berbeda dari initialFilter (ada filter aktif yang sudah di-apply).


Search Methods

setSearchParam()
ts
setSearchParam(param: string): void

Ganti nama query param search (default 'q'). Contoh: setSearchParam('keyword') → param menjadi keyword=... di URL.


getSearchParam()
ts
getSearchParam(): string

Ambil nama query param search saat ini.


submitSearch()
ts
submitSearch(value?: string): void

TIP

NEW v0.4.0

Apply nilai search dan reset pagination ke halaman 1. Gunakan ini saat user submit search baru — mencegah stuck di halaman yang tidak ada di hasil search.

Jika value di-pass, nilai search di-update sebelum reset. Jika tidak, gunakan nilai search yang sudah ada (misal dari v-model).

Contoh:

ts
// Dengan value baru
container.submitSearch('laptop gaming');

// Pakai nilai search yang sudah di-set via v-model
container.submitSearch();

Pagination Methods

declarePagination()
ts
declarePagination(setup: PageSetup): void

TIP

NEW v0.4.0

Deklarasikan intent pagination frontend — set page.setup dan kunci mode. Ini adalah satu-satunya cara yang diizinkan untuk menulis page.setup setelah konstruksi. Harus dipanggil sebelum fetch pertama jika tidak menggunakan QueryIntent.

page.setup bersifat convention-immutable: tidak disentuh oleh mapFromResponse(), hanya berubah lewat method ini atau setPage(null).

Contoh:

ts
container.declarePagination({ mode: 'lengthAware', perPage: 15 });
container.declarePagination({ mode: 'cursor' }); // perPage opsional

setPage()
ts
setPage(config: Partial<PageConfig> | null): void

Override state pagination secara manual. Pass null untuk full reset — termasuk clear page.setup (kembali ke mode auto-detect).


ts
navigatePage(target: number | 'next' | 'prev'): void

Navigasi ke halaman tertentu atau arah berikutnya/sebelumnya. Untuk cursor pagination, 'next'/'prev' menggeser arah cursor.


nextPage()
ts
nextPage(): void

Shorthand navigatePage('next').


prevPage()
ts
prevPage(): void

Shorthand navigatePage('prev').


Sort Methods

setSort()
ts
setSort(sortBy: string, sortDir?: SortDirection): void

Set field dan direction sort. sortDir menerima 'a'/'asc'/1 atau 'd'/'desc'/-1; selalu disimpan sebagai 'asc' atau 'desc'.


setSortAsc()
ts
setSortAsc(sortBy?: string | null): void

Set direction ke ascending. Pass sortBy untuk sekaligus ganti field.


setSortDesc()
ts
setSortDesc(sortBy?: string | null): void

Set direction ke descending. Pass sortBy untuk sekaligus ganti field.


Error Methods

setError()
ts
setError(message: string, code: number | string): void

Set error state secara manual. Juga set loadStatus = -1.


clearError()
ts
clearError(): void

Hapus error state — set error ke null.


URL Methods

getterObjectAttribute()
ts
getterObjectAttribute(): UrlParams

Kembalikan semua state (pagination, sort, filter, search) sebagai plain object. Gunakan sebagai params di axios/fetch.

Contoh:

ts
const res = await axios.get('/api/products', {
  params: container.getterObjectAttribute(),
});

getterUrlStringAttribute()
ts
getterUrlStringAttribute(): string

Kembalikan query string (tanpa leading ?). Berguna untuk manual URL construction atau native fetch.


Utility Methods

reset()
ts
reset(): void

Reset semua state ke kondisi awal: data ke snapshot awal, filter ke initial, search di-clear, pagination ke default, sort di-clear, error di-clear.


mapFromResponse()
ts
mapFromResponse(
  response: ApiResponse,
  mapper?: ((item: unknown) => TData) | null
): void

Map API response ke container state. Set loadStatus = 1 jika berhasil, -1 jika response.success === false.

Perilaku pagination:

  • Jika page.setup sudah di-set (via declarePagination() atau QueryIntent): hanya update state (page number, cursor, total) — mode tidak berubah, perPage tidak ditimpa
  • Jika page.setup null: auto-deteksi mode dari response dan kunci via setup, state sekaligus di-populate

Deteksi mode (saat setup null):

  • lengthAwaremax_page dan total non-null
  • cursornext_cursor atau previous_cursor truthy (non-null, non-empty)
  • simplehas_more non-null
  • none — tidak ada field pagination yang relevan

Expected response shape:

ts
{
  success?: boolean;
  message?: string;
  code?: string | number;
  content?: TData[] | TData;    // data utama
  appended?: TAdditional;       // data tambahan → additionalData
  max_page?: number | null;
  current_page?: number | null;
  total?: number | null;
  next_cursor?: string | null;
  previous_cursor?: string | null;
  per_page?: number | null;
  has_more?: boolean | null;
}

Lihat selengkapnya: mapper


mapper

Optional transform function untuk konversi item raw dari response ke type TData.

Signature:

ts
mapper: (item: unknown) => TData

Contoh:

ts
container.mapFromResponse(res.data, (item: any) => ({
  id: item.id,
  name: item.product_name,   // rename field
  price: Number(item.price), // type coercion
}));

Use Case: Transformasi field names, type coercion, atau penambahan computed fields sebelum data masuk ke container.data.


Types

Contains:

DataContainerObject

ts
interface DataContainerObject<TData, TFilter, TAdditional> {
  // Reactive state
  data: Ref<TData[]>;
  filter: Reactive<TFilter>;
  page: PageConfig;
  sort: SortConfig;
  error: Ref<ErrorInfo | null>;
  additionalData: Ref<TAdditional | null>;
  loadStatus: -1 | 0 | 1;   // getter/setter
  search: string;             // getter/setter
  _appliedFilter: TFilter;   // snapshot, read-only
  _searchConfig: SearchConfig; // snapshot, read-only
  // Computed
  isLoading: ComputedRef<boolean>;
  isLoaded: ComputedRef<boolean>;
  hasError: ComputedRef<boolean>;
  isEmpty: ComputedRef<boolean>;
  // Methods ...
}

Return type dari useDataContainer. Dokumentasi lengkap di useDataContainer Returns.


QueryIntent

ts
interface QueryIntent {
  pagination?: PaginationIntent;
  sort?: SortIntent;
  search?: SearchIntent;
}

Parameter kedua opsional useDataContainer untuk initialize state dari URL.


PaginationIntent

ts
interface PaginationIntent {
  mode: 'none' | 'lengthAware' | 'regular' | 'simple' | 'cursor';
  perPage?: number;
  page?: number;
}

Konfigurasi pagination initial. 'regular' adalah alias 'lengthAware'. Set page.setup pada konstruksi.


SortIntent

ts
interface SortIntent {
  by: string;
  dir?: 'asc' | 'desc';
}

Initial sort state.


SearchIntent

ts
interface SearchIntent {
  param?: string; // default: 'q'
  value?: string;
}

Initial search state.


PageSetup

ts
interface PageSetup {
  mode: PaginationMode;
  perPage?: number | null;
}

Konfigurasi pagination yang dideklarasikan frontend. Convention-immutable — hanya ditulis via declarePagination() atau QueryIntent. mapFromResponse() tidak pernah menyentuh field ini.


PageConfig

ts
interface PageConfig {
  setup: PageSetup | null;  // null = auto-detect dari response
  numeric: {
    current: number | null;
    max: number | null;
  };
  cursor: {
    next: string | null;
    prev: string | null;
    direction: 'next' | 'prev';
  };
  hasMore: boolean | null;
  totalData: number | null;
}

State pagination lengkap. setup adalah konfigurasi frontend (convention-immutable); field lainnya adalah state dari API response.


SortConfig

ts
interface SortConfig {
  sortDir: 'asc' | 'desc';
  sortBy: string;
}

Sort state. sortDir selalu tersimpan sebagai 'asc' atau 'desc'.


SearchConfig

ts
interface SearchConfig {
  searchParam: string;
  searchValue: string;
}

Search state internal — akses via _searchConfig.


PaginationMode

ts
type PaginationMode = 'lengthAware' | 'cursor' | 'simple' | 'none';

Mode pagination. Dibaca via page.setup?.mode.


ErrorInfo

ts
interface ErrorInfo {
  message: string;
  code: number | string;
}

Error state dari API response atau setError().


UrlParams

ts
interface UrlParams {
  perPage?: number;
  page?: number;
  cursor?: string;
  useCursor?: number;
  sortBy?: string;
  sortDir?: string;
  filter?: Record<string, string | string[]>;
  [key: string]: unknown;
}

Return type dari getterObjectAttribute().


← Kembali ke Overview