diceline-chartmagnifiermouse-upquestion-marktwitter-whiteTwitter_Logo_Blue

Today I Learned

Meteor.js powered React hook for retrieving articles with error and loading state handling

The custom hook created uses Meteor's useTracker hook and the subscribe method to subscribe to the article publication, as well as the ArticlesCollection to find the article with the matching _id (which is the same as the slug in this case).

const useArticle = (slug: string): any => {
    const [error, setError] = useState<Error | null>(null)

    return useTracker(() => {
        const sub = Meteor.subscribe('article', { _id: slug })
        if (sub.ready()) {
            const article = ArticlesCollection.findOne({ _id: slug })
            if (article) {
                return {
                    loading: false,
                    error: null,
                    article,
                }
            } else {
                setError(new Error(`Article with slug "${slug}" not found`))
                return {
                    loading: false,
                    error,
                    article: undefined,
                }
            }
        } else {
            return {
                loading: true,
                error: null,
                article: undefined,
            }
        }
    }, [slug, setError])
}

This hook can be used in a React component to display the article, its loading state and error:

const Article = ({ slug }: { slug: string }) => {
    const { loading, error, article } = useArticle(slug)

    if (loading) {
        return <div>Loading...</div>
    }

    if (error) {
        return <div>Error: {error.message}</div>
    }

    return (
        <div>
            <h1>{article.title}</h1>
            <p>{article.body}</p>
        </div>
    )
}