<commit_before>import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
import axios from 'axios';

import { API_PREFIX } from '~client/constants/data';

function buildMakeRequest({ method, url, apiKey, onSuccess, onError, onComplete }) {
    return async (source, id = null, params = {}, data = null) => {
        try {
            let requestUrl = `${API_PREFIX}/${url}`;
            if (id) {
                requestUrl += `/${id}`;
            }

            const res = await axios({
                cancelToken: source.token,
                method,
                url: requestUrl,
                headers: {
                    Authorization: apiKey
                },
                params,
                data
            });

            onSuccess(res.data, id);
        } catch (err) {
            onError(err);
        } finally {
            onComplete();
        }
    };
}

const noop = () => null;

export function useApi({
    method = 'get',
    url,
    apiKey,
    onSuccess = noop
}) {
    const source = useRef(null);

    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);

    const onError = useCallback(err => {
        setError(err);
    }, []);

    const onComplete = useCallback(() => {
        setLoading(false);
    }, []);

    useEffect(() => () => {
        if (source.current) {
            source.current.cancel('Component unmounted');
        }<commit_msg>Optional second completion handler when calling API hook request functions<commit_after>import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
import axios from 'axios';

import { API_PREFIX } from '~client/constants/data';

function buildMakeRequest({ method, url, apiKey, onSuccess, onError, onComplete }) {
    return async (source, id = null, params = {}, data = null, done = null) => {
        try {
            let requestUrl = `${API_PREFIX}/${url}`;
            if (id) {
                requestUrl += `/${id}`;
            }

            const res = await axios({
                cancelToken: source.token,
                method,
                url: requestUrl,
                headers: {
                    Authorization: apiKey
                },
                params,
                data
            });

            onSuccess(res.data, id);
        } catch (err) {
            onError(err);
        } finally {
            onComplete();

            if (done) {
                done();
            }
        }
    };
}

const noop = () => null;

export function useApi({
    method = 'get',
    url,
    apiKey,
    onSuccess = noop
}) {
    const source = useRef(null);

    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);

    const onError = useCallback(err => {
        setError(err);
    }, []);

    const onComplete = useCallback(() => {
        setLoading(false);
    }, []);

    useEffect(() => () => {
        if (source.current) {
            source.current.cancel('Component unmounted');
        }
{'fraction_non_alphanumeric': 0.13274336283185842, 'fraction_numerical': 0.0, 'mean_word_length': 1.6562228024369017, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1317202', 'n_tokens_mistral': 856, 'n_tokens_neox': 836, 'n_words': 208}