I am kind of stumped on this one. I would like to pass an object to another function when I click on a button. That way I can work with the object in the final function.
In this example, I would like to pass the car object from the renderCar function to the makeEditable function when I click on the Edit button.
What I tried:
<button onclick="makeEditable(${car})">Edit</button>
<button onclick="makeEditable(car)">Edit</button>
<button onclick="makeEditable('${car}')">Edit</button>
I can pass in a string like
<button onclick="makeEditable('${car.type}')">Edit</button>
but no success with passing the whole object.
Here I wrote up an example of what I am looking to do.
Fiddle: https://jsfiddle.net/kyleteeter/v8gs05e1/10/
HTML
<div id="root" ></div>
JS
let cars = [
{
"color": "purple",
"type": "minivan",
"capacity": 7
},
{
"color": "red",
"type": "station wagon",
"capacity": 5
}
]
cars.map(car => {
this.root.innerHTML += this.renderCar(car)
});
function renderCar(car) {
return `<div><div data-type="color">${car.color}</div><div data-type="type">${car.type}</div><div data-type="capacity">${car.capacity}</div><button onclick="makeEditable('${car}')">Edit</button></div>`
}
function makeEditable(car){
console.log(car)
}
The problem becomes pretty evident if you look at the generated HTML. In it, you'll have '[object Object]'
just because that's what happens if you try to convert an object into a string, and it's kind of obvious that from this point you can't call makeEditable()
and expect the object to magically appear back - you end up calling the function with '[object Object]'
as an argument and, well, this isn't the object you're looking for.
I'm seeing two possible approaches:
function renderCar(car) {
return `<div><div data-type="color">${car.color}</div><div data-type="type">${car.type}</div><div data-type="capacity">${car.capacity}</div><button onclick="makeEditable('${encodeURI(JSON.stringify(car))}')">Edit</button></div>`;
}
... then, to properly retrieve it, you'd have to reverse the process in the makeEditable()
function:
function makeEditable(data) {
let car = JSON.parse(decodeURI(data));
console.log(car);
}
... but that's kind of ugly and might not always work.
Edit: the approach above using btoa()
and atob()
(instead of encodeURI(JSON.stringify()
and then JSON.parse(decodeURI(data))
respectively) might be better if going this route, I just hadn't thought of that at the time of writing.
let cars = [
{
color: "purple",
type: "minivan",
capacity: 7,
id: "2a93d4e1-9ee9-4490-b4a8-da836cf81d7f",
},
{
color: "red",
type: "station wagon",
capacity: 5,
id: "aa207e90-08d1-434f-afeb-aed1dbd1dab9",
}
];
cars.map((car) => {
this.root.innerHTML += this.renderCar(car);
});
function renderCar(car) {
return `<div><div data-type="color">${car.color}</div><div data-type="type">${car.type}</div><div data-type="capacity">${car.capacity}</div><button onclick="makeEditable('${car.id}')">Edit</button></div>`;
}
function findById(id, array) {
return array.find((e) => e.id === id);
}
function makeEditable(id) {
let car = findById(id, cars);
console.log(car);
}