Need help with Query string

I got the Query string to work by putting the params in the Axios.get url
Now i would like it to adjust the url everytime i type so i can bookmark it, so everytime i go to that exact url it will show the filters that i used, just like a normal webshop page has.

My current Code (in React JS)

const[name,setName]= useState("");
const[description, setDescription]= useState("");
const querystring = require('query-string');

useEffect(() =>{
axios.get(https://localhost:44332/admin/All-products? +  querystring.stringify(
{name, description });
})
},[name,description])

  return (  <div> 
  <input type="text" onChange={(e)=> setName(e.target.value)} />
<input type="text" onChange={(e)=> setDescription(e.target.value)} />
</div>
1 Like
  • You aren’t doing anything with the response, you’re not setting any values.
  • The URL is a string, not a variable
  • You don’t need a library for query parameters, Axios already handles this

For the latter two issues, the request should look like:

axios.get("https://localhost:44332/admin/All-products", { params: { name, description }});

However, for the first issue you should be storing the response in state (like [data, setData] = useState(null), then in the useEffect you call setData with the response from the call)

I would advise looking at the React documentation for how you make calls in useEffect

Thank you for your response, the useffect already contained the async function. but i left it out so it would be easier to read with less code.

this part:

axios.get("https://localhost:44332/admin/All-products", { params: { name, description }});

is exaclty working as it did before, but once i try go to a filtered url like this:

http://localhost:3000/Admin/All-Product?Name=test

(the data contained a product with “test”)
it does not filter at all. what is the correct search url?

and most importantly how can i let react adjust the current url in the url bar to a url with the search filters in it while im typing in the Input field.

Thank you.

useEffect exists to allow you to keep values in the state in sync if they are affected by some side-effect-ful code. So something like:

const [name, setName] = useState (undefined);
const [description, setDescription] = useState(undefined);
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);

useEffect(() => {
  const makeReq = async () => {
    setError(null);
    setLoading(true);
    try {
      const res = await axios.get("https://localhost:44332/admin/All-products", { params: { name, description }});
      setData(res);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
      setName(undefined);
      setDescription(undefined);
    }
  };

  if (name && description) makeReq();
}, [name, description]);

IF the name and description change then rerun the effect. And when that runs, if name and description aren’t undefined then actually run the async function that will populate the data state (or the error state if it fails).

Regarding adjusting it in the URL bar, then that’s not really the job of axios: in that case, you’re not making an AJAX request, you’re literally going to another webpage

Thank your reply.
I understand how useEffect works but thanks for the explanation and effort anyway

What really want know is how i can Change a url so it will save the filters in the url at the same time im typing. and how i can get the filters from the url and apply them in the axios.get

You’re not really explaining things super clearly here: do you mean from the browsers URL bar or just a given URL that you’re going to make an AJAX request with?

do you mean from the browsers URL bar ?

yes

You can’t do that, not while someone types, because the URL bar isn’t part of the document: you don’t have access to someone typing. There are no events fired by someone typing in the address bar. Once they’ve typed something and hit enter, then you have access via the browser History API, so in theory you could use that (probably via a front-end routing framework like React Router) so that when they type a URL, the URL is parsed and stored, then after that you manually push that URL , which causes the router to change state in your app

I have somewhat managed to achive it but its not perfect±

const[SName,setName]= useState("");
const[SDescription, setDescription]= useState("");
 const[data, setData]= useState([]);

 const history = useHistory();
  const querystring = require('query-string');
   const { search } = useLocation()
   const{name,description} = querystring.parse(search)

useEffect(() =>{
(async () =>{
history.push(`?description=${Sdescription}&name=${Sname}`);
const filter = {name,description}
 const res = await axios.get("https://localhost:44332/admin/All-products",{ params: filter}

if(res.status === 200){
setData(res.data);
})()
},[SName,SDescription])

  return (  <div> 
  <input type="text" onChange={(e)=> setName(e.target.value)} />
<input type="text" onChange={(e)=> setDescription(e.target.value)} />
</div>

it kinda works but it has a delay, the url up-dates perfectly but the:

const{name,description} = querystring.parse(search)

does not get the full value of the url params (name and description)
so if I type “test” in the Name input it will look for “tes” it does not look for the last letter or number i typed. even when empty the field it still look for the last character that was in the input so if i typed “test” it would still read “t”

What are useLocation and useHistory? I assume they’re the react router ones but that’s a pretty big chunk of context missing for me. If you’re using RR for everything there shouldn’t be any reason to grab stuff from the URL at all, but need confirmation of that. What exactly is this all doing, and at what point are you wanting to store the filters? Does the user click a button to load the component that contains the filtered data (as in they specify the filters, then click a button to show the list of products)?

[Edit if this an app using React Router] The only reason you should need to manually parse the URL in this case is if you are trying to get params from someone navigating directly to the page (ie they have copy pasted a URL with those parameters already there). Even then you are not using normal browser routing, what you are doing is switching components based on a string which happens to use the browser’s URL bar as the input to the switch. The user never actually leaves the index page, it is entirely handled by RR functionality so you can extract params via the hook the RR API provides

The History ans location is commoning form :

import { useHistory, useLocation } from "react-router";

Like i said I want the axios.get get the filter values form the url.
in that way if reload the page or copy the url and paste it in another browser tab.
it will show the exact same filter results. just like any webstore works.
the only problem is the delay.

Why though? Why not get it from React Router? I feel like you’re making this a lot more complicated than it needs to be. When you make a request to your app, that’s just index.html, it’s not a new page. So when the browser hits the index page, react router will take over using the browser History API, and fill in a URL based on what you’ve defined the routes to be. So when it routes to like admin/All-products?some=filter, you must have defined how to handle the params. If the page reloads, that route is just going to run again. If the URL is copy pasted, that route is just going to run again. Every other web store that uses RR isn’t manually parsing the URLs

Edit:

// To look at the query params
const query = useQuery();

//Then where it's needed
query.get("description")
query.get("name")

?? No need to use history, or look at the URL, or use any other library, just pull the query parameter values from the router

Edit edit, sorry. Missed a key part of that, what the useQuery hook can be like:

function useQuery() {
  return new URLSearchParams(useLocation().search);
}

With useLocation being the RR hook, and URLSearchParams being this. Can still use your parsing library if you want but seems a bit redundant for what it does

Alright but how do i Succesfully update the url on every input change in one of the search fields and at the same time put that search info in Axios.get and make it re-ender, because with my current code I get a delay and only shows the previous added or delete Character

I think I Have found the solution by using a

    const[firstvisit, setfirst]=useState(true);
    useEffect(() =>{
      
(async () =>{

    let filters;
if(!firstvisit){
    filters = {
    "name" : Sname,
    "description": Sdescription,
    "priceMin" : SpriceMin,
    "priceMax": SpriceMax,
    "category" : Scategory}
    history.push(`?name=${Sname}&description=${Sdescription}&priceMax=${SpriceMax}&priceMin=${SpriceMin}&category=${Scategory}`);
}
    else{filters = {name,category,description,priceMax,priceMin}}

        const res = await axios.get("https://localhost:44332/admin/All-products",{ params:filters});

if(res.status === 200){
    setData(res.data);
    setLoading(false)
    setSucces(true);
    console.log(data);
    setfirst(false);
  
}else{
    console.log("failed to get data")
    setLoading(false)
    setfirst(false);
}

when i copy and past the url it will get the params for the Axios.get from the url after the first Render it will set the “FirstVisit” to false allow only the axios.get to get the values from the inputs instead of the Url , i that way i have no delay.

If someone would have a ever better wau please let me know

The react app with the router goes

  • go to index.html
  • match the route in the router (which is the URL you have?)

So in that component, just store the parameters in state somewhere, like a context, if you want them stored.

And if you want them stored when the user clicks the button, you’ve already got them, they are the two values handled by the two useState calls, so again, just store them somewhere.

I don’t understand what you are doing here that you are having so much of an issue with, why you feel the need to actually look at the URL and manually parse all these things to such an extent, when all of this stuff has to already be there

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.