{"id":21174802,"url":"https://github.com/cult-of-coders/grapher-react","last_synced_at":"2025-08-14T00:18:18.016Z","repository":{"id":75851127,"uuid":"68296794","full_name":"cult-of-coders/grapher-react","owner":"cult-of-coders","description":"Provides easy to use  React Components that are suitable for grapher package.","archived":false,"fork":false,"pushed_at":"2023-12-15T09:48:12.000Z","size":47,"stargazers_count":39,"open_issues_count":19,"forks_count":20,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-07-09T23:26:09.838Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://atmospherejs.com/cultofcoders/grapher-react","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cult-of-coders.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2016-09-15T13:35:14.000Z","updated_at":"2025-05-12T08:35:16.000Z","dependencies_parsed_at":"2024-01-23T21:35:23.399Z","dependency_job_id":null,"html_url":"https://github.com/cult-of-coders/grapher-react","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cult-of-coders/grapher-react","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cult-of-coders%2Fgrapher-react","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cult-of-coders%2Fgrapher-react/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cult-of-coders%2Fgrapher-react/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cult-of-coders%2Fgrapher-react/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cult-of-coders","download_url":"https://codeload.github.com/cult-of-coders/grapher-react/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cult-of-coders%2Fgrapher-react/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270337973,"owners_count":24567030,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-13T02:00:09.904Z","response_time":66,"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":[],"created_at":"2024-11-20T16:56:19.457Z","updated_at":"2025-08-14T00:18:17.917Z","avatar_url":"https://github.com/cult-of-coders.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Grapher React Components\n\nUsing the [cultofcoders:grapher](https://github.com/cult-of-coders/grapher) query component in React.\n\n### Installation\n\n```bash\nmeteor add cultofcoders:grapher-react\n```\n\n### Signature\n\n```js\nwithQuery(() =\u003e query, options)(Component);\n```\n\nThe first function needs to return a valid `Query` or `NamedQuery` from Grapher.\n\n```js\n// This is a query\nconst query = createQuery({\n    users: {\n        emails: 1,\n    },\n});\n\n// This is a named query\nconst query = createQuery('usersWithEmails', {\n    users: {\n        emails: 1,\n    },\n});\n```\n\n### Options\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eProperty\u003c/th\u003e\n    \u003cth\u003eValid values\u003c/th\u003e\n    \u003cth\u003eDefault value\u003c/th\u003e\n    \u003cth\u003eDescription\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003ereactive\u003c/td\u003e\n    \u003ctd\u003etrue/false\u003c/td\u003e\n    \u003ctd\u003e`false`\u003c/td\u003e\n    \u003ctd\u003e\n        Makes your query reactive (subscribes to changes) or non-reactive, falls back to method calls.\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003edataProp\u003c/td\u003e\n    \u003ctd\u003estring\u003c/td\u003e\n    \u003ctd\u003e`'data'`\u003c/td\u003e\n    \u003ctd\u003e\n        How to properly inject data in your component, like `users` or `posts`\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eerrorComponent\u003c/td\u003e\n    \u003ctd\u003eReact.Component (optional)\u003c/td\u003e\n    \u003ctd\u003e`null`\u003c/td\u003e  \n    \u003ctd\u003eReceives `error` object as a prop. Is rendered when subscription or method call triggered an exception\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eloadingComponent\u003c/td\u003e\n    \u003ctd\u003eReact.Component (optional)\u003c/td\u003e\n    \u003ctd\u003e`null`\u003c/td\u003e\n    \u003ctd\u003eRenders when the data is waiting to be loaded from the server\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003esingle\u003c/td\u003e\n    \u003ctd\u003etrue/false\u003c/td\u003e\n    \u003ctd\u003e`false`\u003c/td\u003e\n    \u003ctd\u003eIf your query is for a single result, then using `true` will send data as an object instead of an array\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003epollingMs\u003c/td\u003e\n    \u003ctd\u003eNumber\u003c/td\u003e\n    \u003ctd\u003e`undefined`\u003c/td\u003e\n    \u003ctd\u003e\n        Only works for non-reactive queries, it constantly polls for new data every `pollingMs` miliseconds.\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eloadOnRefetch\u003c/td\u003e\n    \u003ctd\u003etrue/false\u003c/td\u003e\n    \u003ctd\u003e`true`\u003c/td\u003e\n    \u003ctd\u003e\n        For static (`reactive = false`) queries only, sets `isLoading` to true every time you call refetch until the data is loaded. Set this to false to only get `isLoading` on the initial fetch.\n    \u003c/td\u003e\n  \u003c/tr\u003e\n      \u003ctr\u003e\n    \u003ctd\u003eshouldRefetch\u003c/td\u003e\n    \u003ctd\u003e(currentProps, nextProps) =\u003e Boolean\u003c/td\u003e\n    \u003ctd\u003e`undefined`\u003c/td\u003e\n    \u003ctd\u003e\n        For static queries only, provides a hook into `componentWillReceiveProps` to determine whether the query should be refetched or not. The function will be called with nextProps and currentProps as arguments.\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n### Simple Usage\n\n```jsx harmony\nimport React from 'react';\nimport { withQuery } from 'meteor/cultofcoders:grapher-react';\n\nconst PostList = ({ data, isLoading, error }) =\u003e {\n    if (isLoading) {\n        return \u003cdiv\u003eLoading\u003c/div\u003e;\n    }\n\n    if (error) {\n        return \u003cdiv\u003e{error.reason}\u003c/div\u003e;\n    }\n\n    return (\n        \u003cdiv\u003e\n            {data.map(post =\u003e (\n                \u003cli key={post._id}\u003e{post.title}\u003c/li\u003e\n            ))}\n        \u003c/div\u003e\n    );\n};\n\nexport default withQuery(props =\u003e {\n    return getPostLists.clone();\n})(PostList);\n```\n\n### Props Received\n\nBelow are the properties received by the component we wrap, in the example above, that's `PostList`\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eProperty\u003c/th\u003e\n    \u003cth\u003eValid values\u003c/th\u003e\n    \u003cth\u003eDescription\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eisLoading\u003c/td\u003e\n    \u003ctd\u003etrue/false\u003c/td\u003e\n    \u003ctd\u003e\n        Lets your component know whether the data is waiting to be loaded.\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eerror\u003c/td\u003e\n    \u003ctd\u003eMeteor.Error\u003c/td\u003e\n    \u003ctd\u003eRepresents the error triggered from your method or publication. If no error it will be a falsy value.\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003erefetch\u003c/td\u003e\n    \u003ctd\u003eFunction\u003c/td\u003e\n    \u003ctd\u003eFor non-reactive queries it passes a refetch function for convenience to help you easily reload the data.\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003equery\u003c/td\u003e\n    \u003ctd\u003eQuery/NamedQuery\u003c/td\u003e\n    \u003ctd\u003eFor your convenience, if you ever need the query for any reason, it's passed in there so you can access it.\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e...props\u003c/td\u003e\n    \u003ctd\u003eObject\u003c/td\u003e\n    \u003ctd\u003eThe props you passed inside withQuery, are passed down to the component it wraps\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n### Let's react!\n\nThe first example uses the query non-reactively (because that is the default). But let's say you want your query to be reactive (react to changes in the database)\n\n```jsx harmony\n// ...\nexport default withQuery(\n    props =\u003e {\n        return getPostLists.clone();\n    },\n    { reactive: true },\n)(PostList);\n```\n\nAs mentioned above, the props received are passed down to the component we wrap, meaning:\n\n```jsx harmony\nconst PostList = ({ data, something }) =\u003e {\n    return \u003cdiv\u003eSomething is true!\u003c/div\u003e;\n};\n\nconst Container = withQuery(\n    props =\u003e {\n        return getPostLists.clone();\n    },\n    { reactive: true },\n)(PostList);\n\nexport default function() {\n    return \u003cContainer something={true} /\u003e;\n}\n```\n\nThe query object is also passed down as a prop, so, if you ever need it you can access it from there.\n\nFor a non-reactive query, we also pass `refetch` function as prop, which simply refetches the query from the database,\nand updates the components properly:\n\n```jsx harmony\nimport React from 'react';\nimport { withQuery } from 'meteor/cultofcoders:grapher-react';\n\nconst PostList = ({ data, isLoading, error, refetch }) =\u003e {\n    return (\n        \u003cdiv\u003e\n            \u003ca onClick={refetch}\u003eReload the data\u003c/a\u003e\n            {/* Rest of the component */}\n        \u003c/div\u003e\n    );\n};\n\nexport default withQuery(\n    props =\u003e {\n        return getPostLists.clone();\n    },\n    { reactive: false },\n)(PostList);\n```\n\nIf you container wraps a single object, and not a list of objects, you can configure your query like this:\n\n```jsx harmony\nconst UserProfile = ({ data, isLoading, error }) =\u003e {\n    return \u003cdiv\u003e{data.email}\u003c/div\u003e;\n};\n\nexport default withQuery(\n    props =\u003e {\n        return getUserProfile.clone({ userId: props.userId });\n    },\n    {\n        single: true,\n    },\n)(UserProfile);\n```\n\nYou will find yourself repeating the same code over and over again for when the query is loading or it has an error. For this you can do:\n\n```jsx harmony\nfunction ErrorComponent({ error }) {\n    return \u003cdiv\u003e{error.reason}\u003c/div\u003e;\n}\n\nfunction LoadingComponent() {\n    return \u003cdiv\u003ePlease wait...\u003c/div\u003e;\n}\n\nconst UserProfile = ({ data }) =\u003e {\n    return \u003cdiv\u003e{data.email}\u003c/div\u003e;\n};\n\nexport default withQuery(\n    props =\u003e {\n        return getUserProfile.clone({ userId: props.userId });\n    },\n    {\n        single: true,\n        errorComponent: ErrorComponent,\n        loadingComponent: LoadingComponent,\n    },\n)(UserProfile);\n```\n\nThe `UserProfile` component will not render if it's loading or it errored.\n\nTo make things even more simple, you can globally define these rules, and all the components by default will have those options.\n\n```jsx harmony\nimport { setDefaults } from 'meteor/cultofcoders:grapher-react';\n\nsetDefaults({\n    reactive: false, // you can default it to true\n    single: false, // doesn't make sense to default this to true\n    errorComponent: ErrorComponent,\n    loadingComponent: LoadingComponent,\n});\n```\n\nYou can override the defaults at the `withQuery` level, for example you want different `error` and `loading` components, you can simply do:\n\n```jsx harmony\nexport default withQuery(\n    props =\u003e {\n        return getUserProfile.clone({ userId: props.userId });\n    },\n    {\n        errorComponent: null,\n        loadingComponent: AnotherLoadingComponent,\n    },\n)(UserProfile);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcult-of-coders%2Fgrapher-react","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcult-of-coders%2Fgrapher-react","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcult-of-coders%2Fgrapher-react/lists"}