/watch-state-api

A util to create api with watch-state

Primary LanguageJavaScriptMIT LicenseMIT

Watch-State logo by Mikhail Lysikov

  @watch-state/api

 

NPM minzipped size downloads changelog license

Api with watch-state
Based on @watch-state/fetch

stars watchers

Install

npm

npm i @watch-state/api

yarn

yarn add @watch-state/api

Usage

Use Api when you want to get data through API

import Api from '@watch-state/api'

const user = new Api('https://reqres.in/api/users/{id}')

Use braces {field} for any dynamic data, so you can create any level API if you want

import Api from '@watch-state/api'

const api = new Api('https://reqres.in/api/{module}/{id}')

Get Fetch of the api with get method

import Api from '@watch-state/api'

const user = new Api('https://reqres.in/api/user/{id}')

const user1 = user.get({ id: 1 })

You can use any option of Fetch with the second argument of Api

import Api from '@watch-state/api'

const user = new Api('https://reqres.in/api/user/{id}', {
  default: {
    data: { id: null }
  }
})

user.get({ id: 1 }).value.data.id
// null

user.get({ id: 1 }).loaded
// false

await user.get({ id: 1 })

user.get({ id: 1 }).value.data.id
// 1

You can setup default data argument.

const user = new Api('https://reqres.in/api/user/{id}', {
  data: {
    id: 1
  }
})

;(await user.get()).data.id
// 1

;(await user.get({id: 2})).data.id
// 2

You can override search params as well

const users = new Api('https://reqres.in/api/users?page={page}', {
  data: {
    page: 1
  }
})

await users.get()
// request to https://reqres.in/api/users?page=1

Or you can provide additional fields for get method to add query search params

const users = new Api('https://reqres.in/api/users', {
  data: {
    page: 1
  }
})

await users.get()
// request to https://reqres.in/api/users?page=1

Cache invalidation

You can update all Fetch instances of an Api with update method

import { Watch } from 'watch-state'
import { Api } from ' @watch-state/api'

const users = new Api('https://reqres.in/api/users?page={page}', {
  data: {
    page: 1
  }
})

new Watch(() => {
  console.log(users.get().value)
})

await users.get()

users.update()

You can update by object keys

import { Watch } from 'watch-state'
import { Api } from ' @watch-state/api'

const users = new Api('https://reqres.in/api/users', {
  getKeys: value => value.data.map(({id}) => id),
})

new Watch(() => {
  console.log(users.get().value)
})

await users.get()

users.update([10])
// nothing happens becase the first page do not contain the user with id equas 10

users.update([1])

TypeScript

Api has 3 generics, the first one is a data type the request will return

interface Responce {
  page: number
  per_page: number
  // ...
}

const users = new Api<Responce>('https://reqres.in/api/users')

console.log(users.get().value?.page)

The second generic is an error type you can get

interface ResponceError {
  code: number
  message: string
}

const users = new Api<any, ResponceError>('https://reqres.in/api/users')

console.log(users.get().error?.message)

The last generic is a data you can provide to the get method

interface Data {
  page: number
}

const users = new Api<any, any, Data>('https://reqres.in/api/users')

await users.get({ page: 1 })

When you don't need a data for the api, it's better to use Fetch instead of, but you can use void type to prevent any query options.

const user = new Api<any, any, void>('https://reqres.in/api/users')

await user.get()

Issues

If you find a bug, please file an issue on GitHub

issues