diff --git a/.github/backup.sql b/.github/backup.sql index 69ae85b..5ba54fc 100644 --- a/.github/backup.sql +++ b/.github/backup.sql @@ -22,4 +22,4 @@ INSERT INTO `functions` (`id`, `title`, `slug`, `description`, `image`, `type`, (13, 'Liste de choses à faire', 'toDoList', 'Prévoyez la liste de choses que vous devez faire.', '/images/functions/toDoList.png', 'page', NULL, NULL, 1, '2019-12-26 00:00:00', '2020-04-27 16:34:34', 1), (14, 'Juste Prix', 'rightPrice', 'Arriverez-vous à deviner le prix d\'un objet ?', '/images/functions/rightPrice.png', 'page', NULL, NULL, 1, '2020-04-27 20:17:05', '2020-04-27 21:59:22', 3), (15, 'Chronomètre', 'chronometerTimer', 'Gérer votre temps facilement (et adopter la technique Pomodoro).', '/images/functions/chronometerTimer.png', 'page', NULL, NULL, 1, '2020-04-29 09:28:08', '2020-04-29 09:45:29', 1), -(16, 'Les méthodes des tableaux', 'arrayMethods', 'Et si on refaisait les méthodes natives de l\'objet global \"Array\" ?', '/images/functions/arrayMethods.png', 'article', '

JavaScript est un langage orienté objet, chaque type comme \"String\",  \"Number\", ... sont en réalité des objets. 
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nCe sont des \"Objets globaux\", qui dispose de méthodes bien utiles. 😎  Pourquoi je vous dit ça ?
\n\n\n\n\n\n\n\n\n\n\n\n\n\nCar aujourd\"hui nous allons reproduire les méthodes de l\"objet global \"Array\",  c\"est un bon exercice pour progresser.
\n
\n\n\n\n\n\n\n\n\n\n\nNous allons réaliser une classe (syntaxe ES6+) qu\"on va appeler \"DivloArray\" par exemple et reproduire 6 méthodes (push, forEach, map, filter, reverse et join), bien évidemment libre à vous d\"en faire plus. 😊 Je vais expliquer le code une méthode après l\"autre donc bout de code par bout de code, si vous voulez avoir le code source complet, il est disponible sur ce GitHub Gist.
\n
\n\n\n\n\n\n\n\n\n\nDonc tout d\"abord, nous devons créer la classe avec un constructor et faire une nouvelle instance de cet objet dans une variable :
\n\n\n\n\n\n\n\n(Libre à vous de renommer les variables comme bon vous semble.) 
\n

class DivloArray {
    constructor(array) {
        this.array = array;
    }
}

\n\n
const divloArray = new DivloArray([574281625]);


\n\n\n\n\n\n- Nous allons commencer par créer la première méthode très utilisée qui consiste à ajouter un ou plusieurs éléments à la fin d\"un tableau, je parle bien évidemment de la méthode push.

/**
 * @description Ajoute un ou plusieurs éléments à la fin d\"un tableau et retourne la nouvelle taille du tableau.
 * @param {*} elements Éléments à ajoutés
 * @returns {Number} La taille (length) du nouveau tableau
 */
push(...elements) {
    let indexCourant = this.array.length;
    elements.forEach((element=> {
        this.array[indexCourant] = element;
        indexCourant++;
    });
    return this.array.length;
}

Alors on prend en paramètre des éléments avec le spread operator ce qui nous permet d\"obtenir un tableau (exemple: 1, 2, 3 devient [1, 2, 3]). On fait une variable indexCourant qui est égale à la taille du tableau qu\"on incrémentera de 1 à chaque tour de boucle, comme ça on peut accéder à l\"index qui n\"existe pas encore et lui attribuer une valeur, l\"élement en cours de la boucle, si vous avez des questions n\"hésitez pas à les poster en commentaire.
\n
\n\n\n\n\n\n- La méthode forEach : 

/**
 * @description Permet d\"exécuter une fonction donnée sur chaque élément du tableau. 
 * @param {Function} callback Une fonction qui accepte jusqu\"à trois arguments :
 * - valeurCourante → La valeur de l\"élément du tableau en cours de traitement.
 * - index → L\"indice de l\"élément du tableau en cours de traitement.
 * - array → Le tableau sur lequel la méthode forEach est appliquée.
 */
forEach(callback) {
    for (let index = 0index < this.array.lengthindex++) {
        const valeurCourante = this.array[index];
        callback(valeurCouranteindexthis.array);
    }
}

Prend une fonction callback, c\"est à dire une fonction qui va être exécutée dans le corps de la fonction et on fait une simple boucle for.
\n
\n\n\n\n\n- La méthode map :

/**
 * @description Crée un nouveau tableau avec les résultats de l\"appel d\"une fonction fournie sur chaque élément du tableau appelant.
 * @param {Function} callback Une fonction qui accepte jusqu\"à trois arguments.
 * - valeurCourante → La valeur de l\"élément du tableau en cours de traitement.
 * - index → L\"indice de l\"élément du tableau en cours de traitement.
 * - array → Le tableau sur lequel la méthode est appliquée.
 * @returns {Array} Un nouveau tableau composé des images de la fonction de rappel.
 */
map(callback) {
    const array = [...this.array]; // permet de ne pas changer les valeurs du tableau original (car passage par référence)
    this.forEach((elementCourantindexCourant=> {
        array[indexCourant] = callback(elementCourantindexCourantthis.array);
    });
    return array;
}


\n\n\n\n- La méthode filter

/**
 * @description Retourne un nouveau tableau contenant tous les éléments du tableau d\"origine qui remplissent une condition déterminée par la fonction callback.
 * @param {Function} callback La fonction de test à appliquer à chaque élément du tableau. Cette fonction est appelée avec les arguments suivants :
 * - elementCourant → L\"élément à traiter
 * - index → Son indice
 * - array → Le tableau complet
 * @returns {Array} Un nouveau tableau contenant les éléments qui respectent la condition du filtre. Si aucun élément ne respecte la condition, c\"est un tableau vide qui est renvoyé.
 */
filter(callback) {
    const resultArray = [];
    this.forEach((elementCourantindexCourant=> {
        const isTrue = callback(elementCourantindexCourantthis.array);
        if (isTrue) {
            resultArray.push(elementCourant);
        }
    });
    return resultArray;
}

Comme on peut le voir beaucoup de ces méthodes recoivent une fonction callback, en tout cas, cette méthode ressemble beaucoup à la méthode map sauf que cette fois çi à la place de faire une assignation on vérifie si la callback nous renvoie True et si oui on push l\"élément à notre tableau de résultats.
\n
\n\n- La méthode reverse qui inverse le tableau : 

/**
 * @description Transpose les éléments d\"un tableau : le premier élément devient le dernier et le dernier devient le premier et ainsi de suite.
 * @returns {Array} Le tableau inversé
 */
reverse() {
    const reverseArray = [];
    for (let index = this.array.length - 1index >= 0index--) {
        const element = this.array[index];
        reverseArray.push(element);
    }
    return reverseArray;
}

On fait l\"inverse de la méthode forEach, à la place de commencer l\"index à 0 et de l\"incrémenter par 1, cette fois çi on commence par le nombre d\"éléments dans le tableau - 1, et on enlève 1 à chaque tour de boucle.
\n
\n- Et pour finir la méthode join :

    /**
     * Crée et renvoie une nouvelle chaîne de caractères en concaténant tous les éléments d\'un tableau
     * @param {String} separator Ce paramètre optionnel indique une chaine de caractères pour séparer chaque élément du tableau
     * @returns {String} Une chaîne de caractères composée de tous les éléments du tableau joints les uns aux autres.
     */
    join(separator = \",\") {
        let resultString = \"\";
        this.forEach((elementindex=> {
            if (this.array.length - 1 === indexreturn resultString += element;
            resultString += element + separator;
        });
        return resultString;
    }

Juste petite subtilité, on ne doit pas rajouter le séparateur à la dernière itrération de la boucle et donc pour ça on fait une simple condition.

Alors ? Ce n\'est pas très compliqué, mais je trouve c\'est important de comprendre comment les méthodes/fonctions fonctionnent avant de s\'en servir et savoir les refaire c\'est toujours un bon plus même si en réalité dans un projet on ne va juste utiliser ces méthodes sans réfléchir comment elles fonctionnent.

', NULL, 1, '2020-04-29 20:16:09', '2020-04-29 21:19:49', 4); \ No newline at end of file +(16, 'Les méthodes des tableaux', 'arrayMethods', 'Et si on refaisait les méthodes natives de l\'objet global \"Array\" ?', '/images/functions/arrayMethods.png', 'article', '

JavaScript est un langage orienté objet, chaque type comme \"String\",  \"Number\", ... sont en réalité des objets. 
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nCe sont des \"Objets globaux\", qui dispose de méthodes bien utiles. 😎  Pourquoi je vous dit ça ?
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nCar aujourd\"hui nous allons reproduire les méthodes de l\"objet global \"Array\",  c\"est un bon exercice pour progresser.
\n
\n\n\n\n\n\n\n\n\n\n\n\nNous allons réaliser une classe (syntaxe ES6+) qu\"on va appeler \"DivloArray\" par exemple et reproduire 6 méthodes (push, forEach, map, filter, reverse et join), bien évidemment libre à vous d\"en faire plus. 😊 Je vais expliquer le code une méthode après l\"autre donc bout de code par bout de code, si vous voulez avoir le code source complet, il est disponible sur ce GitHub Gist.
\n
\n\n\n\n\n\n\n\n\n\n\nDonc tout d\"abord, nous devons créer la classe avec un constructor et faire une nouvelle instance de cet objet dans une variable :
\n\n\n\n\n\n\n\n\n(Libre à vous de renommer les variables comme bon vous semble.) 
\n

class DivloArray {
    constructor(array) {
        this.array = array;
    }
}

\n\n
const divloArray = new DivloArray([574281625]);


\n\n\n\n\n\n\n- Nous allons commencer par créer la première méthode très utilisée qui consiste à ajouter un ou plusieurs éléments à la fin d\"un tableau, je parle bien évidemment de la méthode push.

/**
 * @description Ajoute un ou plusieurs éléments à la fin d\"un tableau et retourne la nouvelle taille du tableau.
 * @param {*} elements Éléments à ajoutés
 * @returns {Number} La taille (length) du nouveau tableau
 */
push(...elements) {
    let indexCourant = this.array.length;
    elements.forEach((element=> {
        this.array[indexCourant] = element;
        indexCourant++;
    });
    return this.array.length;
}

Alors on prend en paramètre des éléments avec le spread operator ce qui nous permet d\"obtenir un tableau (exemple: 1, 2, 3 devient [1, 2, 3]). On fait une variable indexCourant qui est égale à la taille du tableau qu\"on incrémentera de 1 à chaque tour de boucle, comme ça on peut accéder à l\"index qui n\"existe pas encore et lui attribuer une valeur, l\"élement en cours de la boucle, si vous avez des questions n\"hésitez pas à les poster en commentaire.
\n
\n\n\n\n\n\n\n- La méthode forEach : 

/**
 * @description Permet d\"exécuter une fonction donnée sur chaque élément du tableau. 
 * @param {Function} callback Une fonction qui accepte jusqu\"à trois arguments :
 * - valeurCourante → La valeur de l\"élément du tableau en cours de traitement.
 * - index → L\"indice de l\"élément du tableau en cours de traitement.
 * - array → Le tableau sur lequel la méthode forEach est appliquée.
 */
forEach(callback) {
    for (let index = 0index < this.array.lengthindex++) {
        const valeurCourante = this.array[index];
        callback(valeurCouranteindexthis.array);
    }
}

Prend une fonction callback, c\"est à dire une fonction qui va être exécutée dans le corps de la fonction et on fait une simple boucle for.
\n
\n\n\n\n\n\n- La méthode map :

/**
 * @description Crée un nouveau tableau avec les résultats de l\"appel d\"une fonction fournie sur chaque élément du tableau appelant.
 * @param {Function} callback Une fonction qui accepte jusqu\"à trois arguments.
 * - valeurCourante → La valeur de l\"élément du tableau en cours de traitement.
 * - index → L\"indice de l\"élément du tableau en cours de traitement.
 * - array → Le tableau sur lequel la méthode est appliquée.
 * @returns {Array} Un nouveau tableau composé des images de la fonction de rappel.
 */
map(callback) {
    const array = [...this.array]; // permet de ne pas changer les valeurs du tableau original (car passage par référence)
    this.forEach((elementCourantindexCourant=> {
        array[indexCourant] = callback(elementCourantindexCourantthis.array);
    });
    return array;
}


\n\n\n\n\n- La méthode filter

/**
 * @description Retourne un nouveau tableau contenant tous les éléments du tableau d\"origine qui remplissent une condition déterminée par la fonction callback.
 * @param {Function} callback La fonction de test à appliquer à chaque élément du tableau. Cette fonction est appelée avec les arguments suivants :
 * - elementCourant → L\"élément à traiter
 * - index → Son indice
 * - array → Le tableau complet
 * @returns {Array} Un nouveau tableau contenant les éléments qui respectent la condition du filtre. Si aucun élément ne respecte la condition, c\"est un tableau vide qui est renvoyé.
 */
filter(callback) {
    const resultArray = [];
    this.forEach((elementCourantindexCourant=> {
        const isTrue = callback(elementCourantindexCourantthis.array);
        if (isTrue) {
            resultArray.push(elementCourant);
        }
    });
    return resultArray;
}

Comme on peut le voir beaucoup de ces méthodes recoivent une fonction callback, en tout cas, cette méthode ressemble beaucoup à la méthode map sauf que cette fois çi à la place de faire une assignation on vérifie si la callback nous renvoie True et si oui on push l\"élément à notre tableau de résultats.
\n
\n\n\n- La méthode reverse qui inverse le tableau : 

/**
 * @description Transpose les éléments d\"un tableau : le premier élément devient le dernier et le dernier devient le premier et ainsi de suite.
 * @returns {Array} Le tableau inversé
 */
reverse() {
    const reverseArray = [];
    for (let index = this.array.length - 1index >= 0index--) {
        const element = this.array[index];
        reverseArray.push(element);
    }
    return reverseArray;
}

On fait l\"inverse de la méthode forEach, à la place de commencer l\"index à 0 et de l\"incrémenter par 1, cette fois çi on commence par le nombre d\"éléments dans le tableau - 1, et on enlève 1 à chaque tour de boucle.
\n
\n\n- Et pour finir la méthode join :

/**
 * Crée et renvoie une nouvelle chaîne de caractères en concaténant tous les éléments d\'un tableau
 * @param {String} separator Ce paramètre optionnel indique une chaine de caractères pour séparer chaque élément du tableau
 * @returns {String} Une chaîne de caractères composée de tous les éléments du tableau joints les uns aux autres.
 */
join(separator = \",\") {
    let resultString = \"\";
    this.forEach((elementindex=> {
        if (this.array.length - 1 === indexreturn resultString += element;
        resultString += element + separator;
    });
    return resultString;
}

Juste petite subtilité, on ne doit pas rajouter le séparateur à la dernière itrération de la boucle et donc pour ça on fait une simple condition.
\n
\nAlors ? Ce n\"est pas très compliqué, mais je trouve c\"est important de comprendre comment les méthodes/fonctions fonctionnent avant de s\"en servir et savoir les refaire c\"est toujours un bon plus même si en réalité dans un projet on ne va juste utiliser ces méthodes sans réfléchir comment elles fonctionnent.

', NULL, 1, '2020-04-29 20:16:09', '2020-05-06 10:50:26', 4); \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a9ea662 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.github/backup \ No newline at end of file diff --git a/website/components/FunctionsList/FunctionsList.js b/website/components/FunctionsList/FunctionsList.js index 356d014..cf71519 100644 --- a/website/components/FunctionsList/FunctionsList.js +++ b/website/components/FunctionsList/FunctionsList.js @@ -6,10 +6,10 @@ import api from '../../utils/api'; import useAPI from '../../hooks/useAPI'; import './FunctionsList.css'; +let pageFunctions = 1; const FunctionsList = (props) => { const { categoryId } = useRouter().query; - let pageFunctions = 1; // State de recherche et de catégories const [, categories] = useAPI('/categories'); @@ -56,13 +56,13 @@ const FunctionsList = (props) => { const getFunctionsData = async () => { setLoadingFunctions(true); const URL = `${(props.isAdmin) ? "/admin/functions" : "/functions"}?page=${pageFunctions}&limit=10&categoryId=${inputSearch.selectedCategory}&search=${inputSearch.search}`; - const result = await api.get(URL, { + const { data } = await api.get(URL, { headers: { ...(props.isAdmin && props.token != undefined) && { 'Authorization': props.token } } }); setLoadingFunctions(false); - return result.data; + return data; } const handleChange = (event) => { diff --git a/website/pages/functions/randomQuote.js b/website/pages/functions/randomQuote.js index 58826c2..2bdbb5b 100644 --- a/website/pages/functions/randomQuote.js +++ b/website/pages/functions/randomQuote.js @@ -36,7 +36,7 @@ const GenerateQuote = () => { const notyf = new Notyf.Notyf({ duration: 5000 }); - copyToClipboard(`"${quote.quote}" - ${quote.author}`); + copyToClipboard(`"${quote?.quote}" - ${quote?.author}`); notyf.success('Citation copiée dans le presse-papier!'); } @@ -50,15 +50,15 @@ const GenerateQuote = () => {
-

" {quote.quote} "

-

- {quote.author}

+

" {quote?.quote} "

+

- {quote?.author}

Twitter @@ -68,26 +68,22 @@ const GenerateQuote = () => { ); } +let pageQuotes = 1; const QuoteList = () => { const [quotesData, setQuotesData] = useState({ hasMore: true, rows: [], totalItems: 0 }); const [isLoadingQuotes, setLoadingQuotes] = useState(true); - const [pageQuotes, setPageQuotes] = useState(1); - // Récupère les citations si la page change + // Récupère les citations initiales useEffect(() => { - getQuotesData(); - }, [pageQuotes]); + getQuotesData().then((data) => setQuotesData(data)); + }, []); const getQuotesData = async () => { setLoadingQuotes(true); - const { data } = await api.get(`/quotes?limit=20page=${pageQuotes}`); - setQuotesData({ - hasMore: data.hasMore, - rows: [...quotesData.rows, ...data.rows], - totalItems: data.totalItems - }); + const { data } = await api.get(`/quotes?page=${pageQuotes}&limit=20`); setLoadingQuotes(false); + return data; } // Permet la pagination au scroll @@ -97,7 +93,16 @@ const QuoteList = () => { if (observer.current) observer.current.disconnect(); observer.current = new IntersectionObserver((entries) => { if (entries[0].isIntersecting && quotesData.hasMore) { - setPageQuotes(pageQuotes + 1); + pageQuotes += 1; + getQuotesData().then((data) => { + setQuotesData((oldData) => { + return { + hasMore: data.hasMore, + rows: [...oldData.rows, ...data.rows], + totalItems: data.totalItems + }; + }); + }); } }, { threshold: 1 }); if (node) observer.current.observe(node);