How do I make onClick functionality work when I click an image in JSX file using "this"?

Viewed 44

I am trying to have the client make a POST request to to specific endpoint when an image is clicked so that the request data is saved on mongoDB. I am using React-hook and JSX.

The problem is that it seems like the image is not clicked despite the onClick attribute on the image tag. I know this because the console log message in saveFav function does not show up.

edit: the error message shows: "Uncaught (in promise) TypeError: Cannot read property 'getAttribute' of undefined", so the keyword 'this' is undefined. I thought it would refer to the image tag.

I have to hardCode the imgGold property's value without using 'this' or any other ways.

I have tried looking into other questions on this website, but most of them deal with having buttons.

The code of App.js is below:

import React, {useState, useEffect} from 'react';
import axios from 'axios';
const regeneratorRuntime = require("regenerator-runtime");
// import CardBox from './cardBox.js'

const HS = () => {

  const getData = async() => {
    const data = await axios.get('/api/getMoreCards')
    console.log(data)
    setData(data)
}
  const [data, setData] = useState({});
    useEffect(()=>{
      getData()
    },[]);


  // function that send post request when img is clicked
  const saveFav = async () => {
        let body = {
            imgGold: this.getAttribute("id") // returns line 43 id attribute value
        };
    await axios.post('/api/getFavCards', body);
    console.log('img clicked')
    };

    return (
      <>
        <h2 style={{"color": "gold"}}>List of Cards</h2>
        
        {data?.data?.length && (
            <div>
              {data.data[23].name}
              <img id={data.data[23].imgGold} src={data.data[23].img} onClick={saveFav}></img>
            </div>
        )}

export default HS;

in this code, data is an object with the property 'data', whose value is an array of objects. The object element has properties like name, img and imgGold.

Also, my POST and GET request to /api/getFavCards both work, which was tested using Postman application.

Please advise on how to write code for the value of property imgGold inside of saveFav function.

Thank you

2 Answers

Rather than store the value you need in the DOM, a better way to do this would be to pass data.data[23].imgGold directly to saveFav as an argument. Something like:

  const saveFav = async imgGold => {
    let body = {
        imgGold
    };
    await axios.post('/api/getFavCards', body);
    console.log('img clicked')
  };

...

    {data?.data?.length && (
        <div>
          {data.data[23].name}
          <img src={data.data[23].img} onClick={() => saveFav(data.data[23].imgGold)}></img>
        </div>
    )}

If you want to get the image tag id you need to look for it in the target property of the event, which is a reference to the object on which it was fired.

Try changing your saveFav to:

  const saveFav = async (event) => {
        let body = {
            imgGold: event.target.id // Gets the id of the clicked image
        };
    await axios.post('/api/getFavCards', body);
    console.log('img clicked')
    };
Related