{"id":16703514,"url":"https://github.com/kolengri/use-oop-swr","last_synced_at":"2026-05-11T14:31:21.431Z","repository":{"id":57388271,"uuid":"450604674","full_name":"kolengri/use-oop-swr","owner":"kolengri","description":"🍩 Make SWR data sweet again! Transform raw data from SWR to class instance","archived":false,"fork":false,"pushed_at":"2022-01-23T10:26:49.000Z","size":136,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-11T02:45:18.463Z","etag":null,"topics":["class","class-transformer","hooks","oop","react","swr","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kolengri.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-01-21T18:47:24.000Z","updated_at":"2022-01-22T22:59:28.000Z","dependencies_parsed_at":"2022-09-02T04:00:44.747Z","dependency_job_id":null,"html_url":"https://github.com/kolengri/use-oop-swr","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/kolengri/use-oop-swr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kolengri%2Fuse-oop-swr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kolengri%2Fuse-oop-swr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kolengri%2Fuse-oop-swr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kolengri%2Fuse-oop-swr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kolengri","download_url":"https://codeload.github.com/kolengri/use-oop-swr/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kolengri%2Fuse-oop-swr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32898897,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-10T13:40:02.631Z","status":"online","status_checked_at":"2026-05-11T02:00:05.975Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["class","class-transformer","hooks","oop","react","swr","typescript"],"created_at":"2024-10-12T19:08:34.617Z","updated_at":"2026-05-11T14:31:21.239Z","avatar_url":"https://github.com/kolengri.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# use-oop-swr\n\n## OOP useSWR hook wrapper\n\n[![NPM](https://img.shields.io/npm/v/use-oop-swr.svg)](https://www.npmjs.com/package/use-oop-swr)\n[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n[![Badges](https://badgen.net/npm/license/use-oop-swr)](https://www.npmjs.com/package/use-oop-swr)\n[![Badges](https://badgen.net/npm/dependents/use-oop-swr)](https://www.npmjs.com/package/use-oop-swr)\n[![Badges](https://badgen.net/npm/types/use-oop-swr)](https://www.npmjs.com/package/use-oop-swr)\n[![Badges](https://badgen.net/github/issues/kolengri/use-oop-swr)](https://www.npmjs.com/package/use-oop-swr)\n[![Badges](https://badgen.net/bundlephobia/min/use-oop-swr)](https://bundlephobia.com/result?p=use-oop-swr)\n[![Badges](https://badgen.net/bundlephobia/minzip/use-oop-swr)](https://bundlephobia.com/result?p=use-oop-swr)\n\n## Install\n\n### 1. Install package\n\n```bash\nnpm install --save use-oop-swr\n```\n\n```bash\nyarn add use-oop-swr\n```\n\n### 2. Install class-transformer and reflect-metadata\n\n1. `class-transformer` installation\n\n   ```bash\n   npm install class-transformer --save\n   ```\n\n   ```bash\n   yarn add class-transformer\n   ```\n\n2. `reflect-metadata` shim is required, install it too:\n\n   ```bash\n   npm install reflect-metadata --save\n   ```\n\n   ```bash\n   yarn add reflect-metadata\n   ```\n\n   add to the top of index.tsx\n\n   ```tsx\n   import 'reflect-metadata';\n   ```\n\n   or add to `\u003cscript\u003e` `reflect-metadata` in the head of your `index.html`:\n\n   ```html\n   \u003chtml\u003e\n     \u003chead\u003e\n       \u003c!-- ... --\u003e\n       \u003cscript src=\"node_modules/reflect-metadata/Reflect.js\"\u003e\u003c/script\u003e\n     \u003c/head\u003e\n     \u003c!-- ... --\u003e\n   \u003c/html\u003e\n   ```\n\n## Usage\n\nThe aim of this package is to end up with annoying practice of adding properties to data received from api with swr.\n\n### In JavaScript there are two types of objects\n\nplain (literal) objects\nclass (constructor) objects\nPlain objects are objects that are instances of Object class. Sometimes they are called literal objects, when created via {} notation. Class objects are instances of classes with own defined constructor, properties and methods. Usually you define them via class notation.\n\nSo, what is the problem?\n\nSometimes you want to transform plain javascript object to the ES6 classes you have. For example, if you are loading a json from your backend, some api or from a json file, and after you JSON.parse it you have a plain javascript object, not instance of class you have.\n\nFor example you have a list of users in your users.json that you are loading:\n\n```json\n[\n  {\n    \"id\": 1,\n    \"firstName\": \"Johny\",\n    \"lastName\": \"Cage\",\n    \"age\": 27\n  },\n  {\n    \"id\": 2,\n    \"firstName\": \"Ismoil\",\n    \"lastName\": \"Somoni\",\n    \"age\": 50\n  },\n  {\n    \"id\": 3,\n    \"firstName\": \"Luke\",\n    \"lastName\": \"Dacascos\",\n    \"age\": 12\n  }\n]\n```\n\nAnd you have a User class:\n\n```jsx\nexport class User {\n  id: number;\n  firstName: string;\n  lastName: string;\n  age: number;\n\n  getName() {\n    return this.firstName + ' ' + this.lastName;\n  }\n\n  isAdult() {\n    return this.age \u003e 36 \u0026\u0026 this.age \u003c 60;\n  }\n}\n```\n\nYou are assuming that you are downloading users of type User with swr and may want to write following code:\n\n```tsx\nimport * as React from 'react';\nimport axios from 'axios';\nimport useSWR from 'swr';\nimport { User } from './User';\n\nexport type UsersProps = {};\n\nexport const Users: React.FC\u003cUsersProps\u003e = (props) =\u003e {\n  const { data } = useSWR\u003cUser[]\u003e('yourapiendpoint/users', (url) =\u003e\n    axios.get(url).then((res) =\u003e res.data)\n  );\n\n  return \u003cdiv\u003e{JSON.stringify(data)}\u003c/div\u003e;\n};\n```\n\nIn this code you can use users[0].id, you can also use users[0].firstName and users[0].lastName. However you cannot use users[0].getName() or users[0].isAdult() because \"users\" actually is array of plain javascript objects, not instances of User object. You actually lied to compiler when you said that its users: User[].\n\nSo what to do? How to make a users array of instances of User objects instead of plain javascript objects? Solution is to create new instances of User object and manually copy all properties to new objects. But things may go wrong very fast once you have a more complex object hierarchy.\n\nAlternatives? Yes, you can use use-oop-swr. Purpose of this library is to help you to map your plain javascript objects to the instances of classes you have.\n\nThis library also great for models exposed in your APIs, because it provides a great tooling to control what your models are exposing in your API. Here is an example how it will look like:\n\n```tsx\nimport * as React from 'react';\nimport { useOOPSWR } from 'use-oop-swr';\nimport axios from 'axios';\nimport useSWR from 'swr';\nimport { User } from './User';\n\nexport type UsersProps = {};\n\nexport const Users: React.FC\u003cUsersProps\u003e = (props) =\u003e {\n  const [data, swrData] = useOOPSWR(\n    User, // \u003c--- Cool!\n    useSWR('yourapiendpoint/users', (url) =\u003e\n      axios.get(url).then((res) =\u003e res.data)\n    )\n  );\n\n  return \u003cdiv\u003e{JSON.stringify(data)}\u003c/div\u003e;\n};\n```\n\nNow you can use users[0].getName() and users[0].isAdult() methods.\n\n### Arguments\n\n- `classInstance: InstanceType`: Class instance of needly data\n- `swrData:? SWRResponse`: SWR Response object. [Docs](https://swr.vercel.app/docs/getting-started)\n- `options:? ClassTransformOptions`: Options of class-transform plainToInstance function. [Docs](https://github.com/typestack/class-transformer/blob/develop/README.md#plaintoclass)\n\n### Returns\n\nHooks returns array with two items. First class instance with, second one is data from swr hook\n\n## Inspired by\n\n- [SWR](https://swr.vercel.app)\n- [class-transformer](https://github.com/typestack/class-transformer)\n\n## License\n\nMIT © [kolengri](https://github.com/kolengri)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkolengri%2Fuse-oop-swr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkolengri%2Fuse-oop-swr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkolengri%2Fuse-oop-swr/lists"}