Source

hooks/use-fetch.js

import { useEffect, useState } from 'react'

/**
 * This is a custom React Hook that is used to fetch and post data to a REST endpoint.
 * For the equivalent hook for making requests to multiple URL, see {@link useMultipleFetch}.
 * 
 * @category Custom Hooks
 * 
 * @example
 * // Makes a GET request to defined URL
 * const URL= 'www.example.com'
 * useFetch(URL)
 * 
 * @example
 * // Makes a POST request to URL
 * useFetch(URL, 'POST')
 * 
 * @param {string} url The REST endpoint data should be fetched from or posted to.
 * @param {string} [method = GET] The HTTP method to be used in the request. Defaults to a GET request.
 * @param {Object} [body = null] The body of the HTTP request.
 * @param {number} [startTime] The start time for a request given in UTC epoch time. It is also used in refreshing requests at intervals.
 * @param {number} [endTime] The end time for a request given in UTC epoch time.
 * @param {string} [type] The type of the sensor making the request.
 * @returns {Object} returns the data object along with whether there is an error or not.
 */
const useFetch = (url, method = 'GET', body = null, startTime, endTime, type) => {
    const [state, setstate] = useState({isLoading: true, isError: false, data: {}})

    useEffect(() => {
        const myHeaders = new Headers();
        myHeaders.append("x-api-key", "F7BVJtZSo38Hw22aI3QWkLDJ9M0pMc70");
        myHeaders.append("Authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJGbU1ia004UXhyaXozaDl5MzZad0JOaUVZSFZnR0lsTiJ9.sg650g2TmNP9EnMbgA7l9MzciXBkxBTTr6hYHXOz7QI");
        myHeaders.append("X-Host-Override", "wot-device-api");
        myHeaders.append("Content-type", "application/json; charset=UTF-8");

        const requestOptions = {
            method: method,
            headers: myHeaders,
            body: body,
            redirect: 'follow'
        };

        fetch(url, requestOptions)
            .then((resp) => {
                if (resp.status >= 200 && resp.status <= 299 && resp.status !== 204){
                    return resp.json();
                }
                else if(resp.status === 204){
                    if(method === 'POST'){
                        return [
                            {time: new Date(startTime * 1000).toISOString(), value :null},
                            {time: new Date(endTime * 1000).toISOString(), value:null}
                        ]
                    }
                }
                else{
                    setstate({isLoading: false, isError: true, data:{}})
                    throw new Error(resp.statusText);
                }
            })
            .then((resultsObj) => {
                console.log(resultsObj);
                if(method === 'POST'){
                    if (!resultsObj[0].hasOwnProperty('value')){
                        if(type === 'onOff' || type === 'openClose' || type === 'motionDetected'){
                            let firstValue = !resultsObj[0][type]
                            let lastValue = resultsObj[resultsObj.length - 1][type]
                            let firstItem = {time: new Date(startTime * 1000).toISOString(), value :firstValue}
                            let lastItem = {time: new Date(endTime * 1000).toISOString(), value:lastValue}
                            resultsObj = [firstItem, ...resultsObj, lastItem];
                        }
                    }
                    console.log('resultsObj: ' + resultsObj)
                }
                setstate({isLoading: false, isError: false, data: resultsObj})
            })
            .catch((error) => {
                console.log("ERROR> " + error);
                setstate({isLoading: false, isError: true, data: {}})
            });

        return () => {
        };
    }, [url, method, body, startTime, endTime, type])

    return {...state}
}

export default useFetch