2.0.2 • Published 7 months ago

data_providers v2.0.2

Weekly downloads
-
License
ISC
Repository
-
Last release
7 months ago

Data Providers

hooks

useCreateOne

Exposes the createOne method of the provider for convenience

Let's see an example.

Imagine that you have a premium service for creating report and a free version of it, and for premium reports is a must to pass the userId

interface ReportPetitionCreateDTO{
  userId?: string;
  name: string;
  isComplete: boolean;
}

const AskForReportFormFree = ()=>{
  const createOne = useCreateOne<ReportPetitionCreateDTO>('report')

  const onSubmit = (event)=>{
    event.preventDefault()
    const formData = new FormData(event.target)

    const payload =  Object.fromEntries([...formData.entries()])

    createOne(payload)
  }

  return (<form onSubmit={onSubmit}>
      <input name='name' />
      <input name='isComplete' />
      <button type='submit' />
    </form>)
}

const AskForReportPremium = ()=>{
  // This hook is not part of the library, could your custom hook or
  // one provided by a lib
  const user = useUser()

  const createOne = useCreateOne<ReportPetitionCreateDTO>('report', {
    userId: user.id
  })

  const onSubmit = (event)=>{
   event.preventDefault()
    const formData = new FormData(event.target)

    const payload = Object.fromEntries([...formData.entries()])

    createOne(payload)
  }

  return (<form onSubmit={onSubmit}>
      <input name='name' />
      <input name='isComplete' />
      <button type='submit' />
    </form>)
}

Axios and React Query

We love axios api and React Query, here is an example of an implementation with axios

export class ReportService implements IDataProvider{
  constructor(private client: AxiosInstance){}

  appendToken(token: string){
    this.client.defaults.headers.common.Authorization = `Bearer ${token}`
  }

  getOne(params: IGetOneParams){
    const { data } = await this.client.get<IResponseReports>('/reports', {params: {
      id: params.id
    }})

    return data
  }

  getList(params: IGetListParams){
    const { page = 0, limit = 10 } = params?.pagination ?? {}

    const { data } = await this.client.get<IResponseReports[]>('/reports', {params: {
      offset: page*limit,
      limit,
    }})

    return data
  }
}

export class RulesService implements IDataProvider{
  constructor(private client: AxiosInstance){}

  getOne(params: IGetOneParams){
    const { data }  = await this.client.get<IResponseRules>('/rules', {params :{
      name: params.filter.name
    }})

    return data
  }
}

Yes, there should be a single front door, but let's imagine that those microservices actually do not have a front door.

export const reportsClient = axios.create({
  baseURL: import.meta.env.VITE_API_REPORTS_URL
})

export const rulesClient = axios.create({
  baseURL: import.meta.env.VITE_API_RULES_URL
})

export const reportsProvider = new ReportService(reportsClient)

export const rulesProvider = new RulesService(rulesClient)
const providers = {
  reportsProvider,
  rulesProvider
}

export function App(){
  return (
    <DataProvider providers={providers}>
      <ReportsTable />
    </DataProvider>
  )
}
export function ReportsTable(){
  const [ pagination, setPagination ] = useState({
    page: 0,
    limit: 10
  })

  const getReports = useGetList('reportsProvider');


  const { data } = useQuery({
    queryKey: ['reports', pagination.page],
    queryFn: ()=> getReports({pagination})
  })

  return (
    <ul>
      data?.map(({id, name})=>
        <li key={id}>
          {name}
        </li>)
    </ul>
  )
}
import { type ReportService } from '@/services'

const Login = ()=>{
  const login = useLogin()
  const provider = useGetProvider<ReportService>('reportsProvider')

  const { mutateAsync } = useMutation(async (payload: <{username: string; password: string;}>)=>{
    const { token } = await login(payload)

    provider.appendToken(token)
  })
  const onSubmit = (event)=>{
    event.preventDefault()
    const formData = new FormData(event.target)

    const payload = Object.fromEntries([...formData.entries()])

    mutateAsync(payload)
  }
  return (<form>
    <input name="username" >
    <input name="password" >
  </form>)
}
2.0.2

7 months ago

2.0.1

7 months ago

2.0.0

7 months ago

1.0.5

7 months ago

1.0.4

7 months ago

1.0.3

7 months ago

1.0.2

8 months ago

1.0.1

8 months ago

1.0.0

8 months ago