skip to Main Content

I have a problem knowing the data type of the URL that I WILL res API from it, and I am using a custom hook to make it usable I am using Next.js with typescript

this is a useFetch.js (custom hook)

"use client"
import { useState } from "react";

type FetchParams = {
  url: any
}

async function getData(url: FetchParams) {
  try {
    const res = await fetch(url.toString())
    return res.json()
  } catch(error) {
    console.log("error", error);
  }
}

export default async function useFetch(url: FetchParams) {
  const [data, setData] = useState("")
  setData(await getData(url))
  return { data };
}

This is a pray components

import useFetch from '@/Hooks/useFetch';
import { useState, useEffect } from 'react';

export default function Pray() {
  // Date methods
  let date = new Date();
  let month = date.getMonth() + 1;
  let year = date.getFullYear();
  // day equal date - 1
  let day = date.getDate()-1;

  const [country, setCountry] = useState('eg')
  const [city, setCity] = useState('cairo')

  const [data, setData] = useState("")
  
  useEffect(() => {
    const { data }: any = useFetch(`https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`)
    console.log(data)  
  }, [data])
  
  return()
}

error is:

Argument of type ‘string’ is not assignable to parameter of type
‘FetchParams’.ts(2345)

const { data }: any = useFetch(`https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`)

3

Answers


  1. To fix this, you need to pass an object instead of a string to the useFetch as a parameter:

    const {data}: any = useFetch({url: `https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`})
    
    Login or Signup to reply.
  2. You have declared useFetch to consume a FetchParams type argument, not a string type argument.

    Update useFetch to consume a URL string type value. Don’t forget to use a useEffect hook to issue the side-effect of making the fetch and updating the data state.

    "use client"
    import { useState } from "react";
    
    async function getData(url: string) {
      try {
        const res = await fetch(url);
        return res.json();
      } catch(error) {
        console.log("error", error); 
      }
    }
    
    export default async function useFetch(url: string) {
      const [data, setData] = useState("");
    
      useEffect(() => {
        getData(url).then(setData);
      }, [url]);
    
      return { data };
    }
    

    Alternatively you could pass an object:

    type FetchParams = {
      url: string
    }
    
    async function getData(fetchParams: FetchParams){
      try {
        const res = await fetch(fetchParams.toString());
        return res.json();
      } catch(error) {
        console.log("error", error); 
      }
    }
    
    export default async function useFetch(fetchParams: FetchParams) {
      const [data, setData] = useState("");
    
      useEffect(() => {
        getData(url).then(setData);
      }, [fetchParams]);
    
      return { data };
    }
    
    const { data }: any = useFetch({
      url: `https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`
    });
    

    The useFetch hook can’t be called from within the useEffect hook’s callback function. It must be called as the top-level of the component or other custom React hooks. Remove the data state and simply reference the useFetch hook’s returned value.

    export default function Pray() {
      // Date methods
      let date = new Date();
      let month = date.getMonth() + 1;
      let year = date.getFullYear();
      // day equal date - 1
      let day = date.getDate()-1;
    
      const [country, setCountry] = useState('eg');
      const [city, setCity] = useState('cairo');
    
      const { data }: any = useFetch(
        `https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`
      );
      
      return (....);
    }
    
    Login or Signup to reply.
  3. The error you are getting is because you have assigned the interface to your object and then you are directly passing it value to it. Your url object is something like this:

    url:{url:string} instead of being url:string
    

    So you need to change your way of declaring the object or pass your object as a child object:

    Declare the url object the correct way

     export default async function useFetch({url}: FetchParams) { 
     const [data, setData] = useState("")
     setData(await getData(url))
      return { data };
    }
    

    Or send url in an object

    const {data}: any = useFetch({url: `https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`})
    

    Also I think your useFetch function is unnecessary here, you can just directly call your getData function.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search