npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@rest-api/react-models

v2.2.8

Published

[![npm version](https://img.shields.io/npm/v/@rest-api/react-models)](https://www.npmjs.com/package/@rest-api/react-models) [![codecov](https://codecov.io/gh/hector7/rest-api-react-models/branch/master/graph/badge.svg)](https://codecov.io/gh/hector7/rest-

Downloads

32

Readme

@rest-api/react-models

npm version codecov

Make your React project easier to maintain with this package.

Benefits:

  • You will gain a more typed project (if you are using Typescript)
  • All ajax calls are stored on redux, your endpoint is only called on necessary
  • Better structure on your project

Caution: if you have some random typescript error (pex: ts2589) on creating or editing models, kill the process and restart npm start (on Visual Studio Code restart program).

Features

  • Added nullable argument to schema fields
  • Added initialized variable for all requests (if not initialized, is not requested)

Major changes

From v1

  • Upgraded typescript version and needs your proyect version >=3.9.3 (and react-scripts >= 3.4.1, if you don't eject your project)
  • Required and idOnly don't need to import from library since upgraded typescript version
  • A model on a schema represents the schema of model (for represent the primary key, needs to pass idOnly argument)
  • Connect methods deleted (deprecated on v1)
  • Added more flexibility on models generation adding methods ("getSubModelWithKey" and "getSearchSubModel") to models

From v0

  • On model creation don't need to pass a model name. This major includes a refactor and some bug fixes and features.

File structure

This code examples follows this src structure:

src
└-- models
|   └-- bookModel.ts
|   └-- libraryModel.ts
└-- containers
|   └-- bookContainer.tsx
|   └-- libraryContainer.tsx
└-- views
|   └-- bookView.tsx
|   └-- libraryContainer.tsx
└-- index.tsx

Provider

First of all you need to insert on your index.tsx the provider from application.

...
import { getProvider } from  '@rest-api/react-models';

const ReactModelsProvider = getProvider();


ReactDOM.render(<ReactModelsProvider>
    <App />
</ReactModelsProvider>, document.getElementById('root'));

Declaring models

Declare the models of your application, given a Schema, an id (need to be required field) and a base url:

import { Model, Schema } from  '@rest-api/react-models'

const librarySchema = Schema({
    id: {
        type: Number,
        required: true
    },
    name: String
})
export  default  new  Model(librarySchema, 
    'id', // must be declared as required, string or number and not array or null
    '/api/library')

You can use complex objects on a Schema simplier creating subschemas:

import { Schema } from  '@rest-api/react-models'

const testSchema = Schema({
    subSchema: Schema({
        id: { type: String },
        name: String
    })
})

Represent a field which can be null:

import { Schema } from  '@rest-api/react-models'

const testSchema = Schema({
    nullableField: { 
        type: String, 
        nullable: true, 
        required: true 
    }
})

For a model with metadata, you can represent with following arguments (declaring the data that endpoint sends):

import { Model, Schema } from  '@rest-api/react-models'

const librarySchema = Schema({
    id: {
        type: Number,
        required: true
    },
    name: String
})
export  default  new  Model(librarySchema, 
    'id', 
    '/api/library',
Schema({
    count: {
        type: Number,
	required: true
    },
    items: [{
        type: librarySchema,
	required: true
    }]
},
data => data.items,
({items, ...metadata}) => metadata,
{} //here optional opts (trailingSlash and headers)
)
	

And foreign keys of your model can be representated:

import { ModelType, ModelPopulatedType, Schema, Model } from  '@rest-api/react-models'
import libraryModel from './libraryModel'

const bookSchema = Schema({
    id: { type: Number, required: true },
    name: { type: String, required: true },
    description: String,
    library: {
        type: libraryModel,
        required: true,
        idOnly: true
    }
})
export type BookType = ModelType<typeof bookSchema>
export type BookPopulatedType = ModelPopulatedType<typeof bookSchema>
export default new Model(bookSchema, 'id', '/api/book')

An option can be passed to model declaration in order to works with django "trailing slash" or pass custom headers:

new Model(bookSchema, 'id', '/api/book', { trailingSlash: true, headers: { Authorization: "Basic xxxx" } })

New methods of model

If you has an endpoint on a different url that represents same object, now you can use your declared model

getSubModelWithKey method

In order to get an object by a key (not an id, but is unique) this is your method Simple usage:

import bookModel from './bookModel'
export default bookModel.getSubModelWithKey('name', '/api/book/name') 

//url is optional, if not provided will be used url from bookModel

Full control on your url:

import bookModel from './bookModel'
import { Schema } from '@rest-api/react-models'
const optSchema = Schema({ 
    project: { 
        type: Number, 
        required: true 
    }
})
export default bookModel.getSubModelWithKey(optSchema, 'name', ({project}) => `/api/book/${project}/name`)

getSearchSubModel method

This method is in order to work as "useGet" or "useGetPopulated", but in other url

Simple usage:

import bookModel from './bookModel'
export default bookModel.getSearchSubModel('api/book/hector') 

Full control on your url:

import bookModel from './bookModel'
import { Schema } from '@rest-api/react-models'
const optSchema = Schema({ 
    author: { 
        type: String,
        required: true 
    }
})
export default bookModel.getSearchSubModel(optSchema, ({author}) => `/api/book/${author}`)

Using on the container

Simple usage

Once you have created a model, you can use it on a container!

Fist clean mode using Typescript, using a hook:

import  React  from  'react'

import  bookModel  from  '../models/bookModel'
import  BookView  from  '../views/bookView'


export default () => {
	const { items, loading, error, initialized } = bookModel.useGet()
    if (!initialized) <p>Request not fetched</p>
	if (error) return  <p>There are an error with the request</p>
	if (loading) return  <p>Loading...</p>
	return  <ul>{
		items.map(i  =>  <BookView  name={i.name}  />)
	}</ul>
}

Populate items

This feature populate foreign key if these ones aren't fetched. It's recommended to fetch beore this call the objects using useGet (pex: on Apps initialization). The ajax method will be called only on necessary (if there are some object not fetched).

You can populate items with a simple usage (you need to check if it's populated, if you want to use a placeholder):

import React from 'react'

import bookModel from '../models/bookModel'

export default () => {
    const { loading, error, ...result } = bookModel.useGetPopulated()

    if (error) return <p>There are an error with the request</p>
    if (loading) return <p>Loading...</p>
    return <table>
	<thead>
	    <tr>
		<th>Id</th>
		<th>Name</th>
		<th>Library name</th>
	    </tr>
	</thead>
	<tbody>
	    {
		result.populated ?
		result.items.map(i => <React.Fragment key={i.id}>
		    <td>{i.id}</td>
		    <td>{i.name}</td>
		    <td>{i.library.name}</td>
		</React.Fragment>) :
		result.items.map(i => <React.Fragment key={i.id}>
		    <td>{i.id}</td>
		    <td>{i.name}</td>
		    <td>{i.library.name ?? 'Loading ...'}</td>
		</React.Fragment>)
	    }
	</tbody>
    </table>
}

Use methods (POST, PUT, PATCH, DELETE)

In order to access to one of those methods, select the correct hook (usePost, usePut, usePatch or useDelete)

import React from 'react'

import { ModelType, HttpError } from '@rest-api/react-models'
import bookModel from '../models/bookModel'
import { useHistory } from 'react-router-dom'

export default () => {
    const post = bookModel.usePost()
    const [data, setData] = React.useState<ModelType<typeof bookModel>|null>(null)
    const history = useHistory()
    const [error, setError] = React.useState<HttpError|null>(null)
    
    function handleSubmit(ev){
        ev.preventDefault()
        if(data)
            post(data, (err, res) => {
                if(err) //there are an error with request
                    return setError(err)
                history.push('to the new path')
            })
    }

    return ...
}