2

I want to pass a dynamic object in onclick jQuery. Please check the below snippet in which I am getting object product value as undefined. Can someone help me on how to pass and receive object value in JavaScript/jQuery?

var hpc = "";

function handleProductsClick(e, product) {
  debugger;
  alert(product && JSON.stringify(product));
}

function buildProducts(products) {
  var bp = '';
  hpc = handleProductsClick.bind(products[i]);
  for (var i = 0; i < products.length; i++) {
    bp += '<li onclick="hpc(event)">' + products[i].value + '</li>';
  }
  $("#products").html(bp);
}

function getProductsFromApi() {
  var products = [{
      key: 1,
      value: "Apple"
    },
    {
      key: 2,
      value: "Android"
    }
  ];
  buildProducts(products);
}

getProductsFromApi();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul id="products"></ul>

3
  • hpc = handleProductsClick.bind(products[i]); in this line i is undefined Commented May 28, 2018 at 10:25
  • Do you want to alert the id when you click on 'li' ?? Commented May 28, 2018 at 10:25
  • What dynamic object are you trying to pass? Commented May 28, 2018 at 10:28

3 Answers 3

3

Try attaching the listener properly using event listeners in Javascript rather than inline HTML attributes (which is as bad as eval). Also, when you use bind, the first argument is the this value provided to the function; the second argument to .bind corresponds to the first argument in the other function.

function handleProductsClick(product) {
  console.log(product && JSON.stringify(product));
}

function buildProducts(products) {
  products.forEach(product => {
    const li = $('<li>' + product.value + '</li>');
    li.on('click', handleProductsClick.bind(null, product));
    $("#products").append(li)
  });
}

function getProductsFromApi() {
  var products = [{
      key: 1,
      value: "Apple"
    },
    {
      key: 2,
      value: "Android"
    }
  ];
  buildProducts(products);
}

getProductsFromApi();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul id="products"></ul>

Sign up to request clarification or add additional context in comments.

4 Comments

Is there a way we can use html() instead of append()?
No, because html only sets an HTML string, not an actual element. (strings can't have listeners attached to them; elements can.) Definitely use append.
Ok. But is there any performance issue if I use append instead of html?
No performance issue, performance is almost never something worth worrying about anyway
1

It will be better to avoid the use of inline onclick, and try to attach the event to the li or to common classes, the n use data-* attributes to pass the information you want :

$(function() {
  $('body').on('click', '.my_item', function() {
    console.log($(this).data('product'));
  });
});

function buildProducts(products) {
  for (var i = 0; i < products.length; i++) {
    $("#products").append("<li class='my_item' data-product='" + JSON.stringify(products[i]) + "'>" + products[i].value + "</li>");
  }
}

function getProductsFromApi() {
  var products = [{
      key: 1,
      value: "Apple"
    },
    {
      key: 2,
      value: "Android"
    }
  ];

  buildProducts(products);
}

getProductsFromApi();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul id="products"></ul>

Comments

0

try this

var hpc = "";

function handleProductsClick(e, product) {
  debugger;
  alert(product && JSON.stringify(product));
}

function buildProducts(products) {
  var bp = '';
  hpc = handleProductsClick.bind(products[i]);
  for (var i = 0; i < products.length; i++) {
    bp += '<li onclick="hpc(event)">' + products[i].value + '</li>';
  }
  $("#products").html(bp);
}

function getProductsFromApi() {
  var products = [{
      key: 1,
      value: "Apple"
    },
    {
      key: 2,
      value: "Android"
    }
  ];
  buildProducts(products);
}

getProductsFromApi();

Comments

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.