0

Not sure if the title makes sense but, I want to send data with an click event, this click event will get the data from a pre set var (in this case product101), as this var is formatted in JSON I cant seem to retrieve the data, it always returns a undefined. As the var is an object, but when I use the dataset var is an string right?

 // inside a loop
 <div class="container">

     <script> var product<?=$id?> = {"category":"cars"}</script>

     <div data-my-product="product<?=$id?>">
         //all the product stuff
     </div>

 </div>

 //located in the footer
 $('[data-my-product]').click(function(){

      //demo
      var pro = $(this).data('my-product');
      alert(pro.category);//returns undefined

 })

When I click the product it returns a 'undefined' alert message.

Notice that the products are generated inside a loop.

user759235
  • 2,147
  • 3
  • 39
  • 77
  • Your data attribute contains only the string "product101". In order to get that object from `.data()` you have to actually put the JSON text in the attribute value directly. – Pointy Aug 06 '18 at 12:33
  • Yes I know sadly due the several events set around this it needs to be a seperate set var/obj. – user759235 Aug 06 '18 at 12:35
  • `$(this).data('my-product') === "product101"`. It's not equal to the _value_ of `"product101"`, it is equal _to_ `"product101"`. – Jeremy Thille Aug 06 '18 at 12:39
  • attr or data, same issue – user759235 Aug 06 '18 at 12:39
  • @deepakthomas no `.data()` is correct. OP you cannot do what your code tries to do. The HTML parser has no awareness of the JavaScript context. – Pointy Aug 06 '18 at 12:39
  • Neither your question nor your code contains JSON. Please read [What is the difference between JSON and Object Literal Notation?](https://stackoverflow.com/questions/2904131/what-is-the-difference-between-json-and-object-literal-notation) – str Aug 06 '18 at 12:47
  • str, yeah you are right, my bad ;-) – user759235 Aug 06 '18 at 12:55

1 Answers1

1

Overview

Your best bet here is to create an object or Map with the things you want to look up this way, and then put them on it as properties or entries.

With an object:

var items = {
    product101: {category: "cars"}
};

or if you want to be paranoid about the default inherited properties that exist on objects, you might use an object with no prototype:

var items = Object.create(null);
items.product101 = {category: "cars"};

then in your click handler:

alert(items[pro].category);

Live Example:

$('[data-my-product]').click(function() {
  var pro = $(this).data('my-product');
  alert(items[pro].category);
});
<div class="container">

  <script>
    var items = {
        product101: {category: "cars"}
    };
  </script>

  <div data-my-product="product101">
    //all the product stuff
  </div>

</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

With a Map:

var items = new Map([
    ["product101", {category: "cars"}]
]);

then in your click handler:

alert(items.get(pro).category);

Live Example:

$('[data-my-product]').click(function() {
  var pro = $(this).data('my-product');
  alert(items.get(pro).category);
});
<div class="container">

  <script>
    var items = new Map([
        ["product101", {category: "cars"}]
    ]);
  </script>

  <div data-my-product="product101">
    //all the product stuff
  </div>

</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Side note: Although you can access that data-* attribute's value (indirectly) using data, doing so sets up a data cache for the element and initializes that cache with the attribute's value. If you're just looking to get the string, .attr("data-my-product") is more direct. See this answer for more details.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • thanks but not sure how to use this with a click event – user759235 Aug 06 '18 at 12:41
  • @user759235 - You literally use the "then in your click handler" line in place of the `alert` in your question's code. I've added live examples. – T.J. Crowder Aug 06 '18 at 12:45
  • @user759235 - Yes, they do. See the live examples. – T.J. Crowder Aug 06 '18 at 15:00
  • okay strange, when I click the 'run code snippet' button I see a error message – user759235 Aug 06 '18 at 15:02
  • { "message": "Script error.", "filename": "", "lineno": 0, "colno": 0 } – user759235 Aug 06 '18 at 15:10
  • @user759235 - Sounds like whatever browser you're using isn't compatible with Stack Snippets, then. But if you actually try the code, it will work. – T.J. Crowder Aug 06 '18 at 15:17
  • im using chrome on OSX, but when I use the code the result is still undefined – user759235 Aug 06 '18 at 15:25
  • @user759235 - All due respect, I find it **very** hard to believe the snippets above don't work on Chrome on OSX. I've checked, and they work on Chrome on Linux, iOS, and Windows. But again, you can just copy the code and run it locally. If you're getting "undefined," you've copied the code incorrectly. – T.J. Crowder Aug 06 '18 at 15:31
  • 1
    In both cases (Chrome OSX) I get a popup saying "Cars" – JockM Aug 06 '18 at 15:41
  • Well if you dont believe me, take a look at the image https://ibb.co/eqpA5e – user759235 Aug 07 '18 at 09:44
  • @user759235 - Don't know what more I can say. The code works. If you have a problem with stack snippets with your particular installation, just copy the code into your project (correctly) and it will work. Note that that image shows the `Map` version. If you have a ***really*** obsolete version of Chrome installed, it may not have `Map`. But we're talking ***really*** obsolete, and the first snippet will work in any case. BTW, to see the *real* error, open the web console. What the snippet console shows isn't all that useful. – T.J. Crowder Aug 07 '18 at 09:48
  • Found the issue, as I use it in a loop, this will prevent it from working, when I only use one name (id) t will work. – user759235 Aug 07 '18 at 13:24