1

I have an API that gives me a random location each time I recall the API, and I want the button to just re-call the API.

I tried to use an arrow function and a normal function but I get a different error; my general idea is to wrap the fetching method with a function and then call this function twice, the first call before I render the component and the second call on this button.

These are my attempts:

(Note: my buggy function is handleOnClick)

 state = {
   isLoading: true,
   shop: null, 
   error: null
 };

 componentDidMount() {
   // fix CORB and CORS issues by using proxy
   var proxyUrl = 'https://cors-anywhere.herokuapp.com/',
     targetUrl ='https://wainnakel.com/api/v1/GenerateFS.php?uid=26.2716025,50.2017993&g%20et_param=value';

     function handleOnClick() {
       fetch(proxyUrl + targetUrl)
     .then(res => res.json())
     .then(shop => {
       console.table(shop); // create table in console 
       this.setState({ 
         shop ,
         isLoading:false,
       });
     })
     .catch(e => {
       console.log(e);
     });    
   }

   handleOnClick();
 }


   showLocation = () => {
   var location = `${this.state.shop.lat}%2C%20${this.state.shop.lon}`;
  var gmapurl =`https://maps.google.com/maps?q=${location}&t=&z=17&ie=UTF8&iwloc=&output=embed`;
  return gmapurl;
};



 render() {

   const { isLoading, shop, error } = this.state; //no need to write this.state every time



   let gmapurl ;  //create variable that we will store the new location from the API 

   return (  


     <React.Fragment>
          <Navigation />

     <div> 
     {/* // Display a message if we faced an error */}
     {error ? <p>{error.message}</p> : null} 
     {!isLoading ? ( //   check data if it ready 
     //and take lat and lon from api ,and place it in  embedded google map url
    gmapurl =`https://maps.google.com/maps?q=${this.state.shop.lat}%2C%20${this.state.shop.lon}&t=&z=17&ie=UTF8&iwloc=&output=embed`,

       shop ? (
         <div>

           <h1> {this.state.shop.name}</h1>
        {/* MAP */}  
        <div className="mapouter MapPage"><div className="gmap_canvas">
           <iframe width="768" height="500" id="gmap_canvas" src={gmapurl} 
           frameBorder="0" scrolling="false" marginHeight="0" marginWidth="0">
           </iframe>
           <h1>map veiw</h1></div> 
           </div>


           <button className="btn" onClick={() =>  {handleOnClick}}> <div className="lds-ellipsis"><div></div><div></div><div></div><div></div></div>أقتراح آخر</button>

        </div> ) : ( '')
):(      // show loading icon if there is a delay in data
<div> <img src={loadingpic}></img>  </div>
 )
     }
     </div>
     </React.Fragment>
   );
 }
}

and this the error I got


  Line 82:  Expected an assignment or function call and instead saw an expression no-unused-expressions

  Line 82:  'handleOnClick' is not defined  no-undef

4
  • 1
    It's not quite clear to me how these different tries are related. Could you please edit your question to show the most promising try in a complete way? Commented Apr 24, 2019 at 6:49
  • @JonasWilms okay Commented Apr 24, 2019 at 6:51
  • @JonasWilms sorry, I just realize that I overwrite on your edit! Commented Apr 24, 2019 at 7:00
  • Thats fine, it is still your question, and you actually did not revert my edit :) Commented Apr 24, 2019 at 7:02

1 Answer 1

2

Your handleOnClick is a local function, that can only be called from inside componentDidMount. To be able to call it from anywhere inside the class, use a method. Maybe the name should be a bit more descriptive of the task that it actually does, e.g. loadShop:

 loadShop() {
   this.setState({ isLoading: true });

  fetch(proxyUrl + targetUrl)
    .then(res => res.json())
    .then(shop => {
      console.table(shop);
      this.setState({ 
         shop ,
         isLoading:false,
      });
     });
 }

Then you can call it from anywhere inside the class as this.loadShop(), e.g.

 <button onClick={() => this.loadShop()} >
Sign up to request clarification or add additional context in comments.

2 Comments

In the solution, proxyUrl and targetUrl are now out of scope variables. @JonasWilms you should adjust your answer to either redefine them in loadShop or suggest making them scoped so both loadShop and componentDidMount functions can access them.
thank you so for the help! it works with some edit You can define proxyUrl targetUrl above the class inside the same file. and put loadShop() outside the componentDidMount()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.