-1

I have a web app, where the user can hit a button to copy an engine object.

I wrote the method below in Javascript, and it works. However, if more than 2 or 3 users are cloning, random errors will pop-up. For example, it will say, Engine is undefined or engineToClone is undefined.

But if only one person is doing it, it never has errors.

So I am wondering if there is a better way to write this:

    var engineToClone = this.model;

    var clonedEngine = new Engine({
        factoryId: engineToClone.attributes.factoryId,
        title: 'CLONED OF - ' + engineToClone.attributes.title,
        engineDescription: engineToClone.attributes.engineDescription,
        isFrontend: engineToClone.attributes.isFrontend,
        cylinders: engineToClone.cylinders,
        headers: engineToClone.headers,
        vehicles: engineToClone.vehicles,
        pistons: engineToClone.pistons,
        fuels: engineToClone.fuels
    });
    
    clonedEngine.save(null, {
        url: self.factory.url()
    }).done(function () {
    });

I tried doing this, but it generates null values:

    var engineToClone = this.model;

    var clonedEngine = engineToClone;

But the clonedEngine is always comes back as null.

I also read an answer on here to use json, so I tried this:

JSON.parse(JSON.stringify(engineToClone))

But it always says JSON is undefined.

So I must be doing something wrong and I was hoping someone could point me in the right direction.

Thanks!

SkyeBoniwell
  • 5,272
  • 8
  • 62
  • 128
  • 1
    JSON is undefined? What runtime / browser are you using? Are you using compatibility mode? – Jacob Lockwood Apr 29 '21 at 23:03
  • @JacobLockwood thank you, I am using the latest version of Fire Fox. It is in compatibility mode. – SkyeBoniwell Apr 29 '21 at 23:08
  • 1
    that must be your issue... In compatibility mode, JSON is not defined, as it was not supported in IE 7 and below. Just turn compatibility mode off and you'll be good to go. – Jacob Lockwood Apr 29 '21 at 23:17

2 Answers2

1

The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the target object. Read this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

1

It's odd that JSON is undefined, but there is another solution using Object.assign(). Basically, it takes each of the properties from the original object and copies it onto {}.

const myObject = {
  some: "properties",
  that: "could",
  be: "cloned",
}

let clone = Object.assign({}, myObject);

myObject.x = 
  "the original was edited... what happens to the clone?";

console.log(clone);

Note that this is a "shallow copy." If myObject has nested objects, and those are later edited, the copy will also be affected. If you need a "deep copy," you should use the JSON.parse(JSON.stringify(object)) solution.


If you need to copy all properties except for a few, you can use this:

const clone = (obj, ...ignore) => {
  let copy = Object.assign({}, obj); //copy the object
  for (var i of ignore) delete copy[i]; //delete everything from ignore
  return copy; //return what's left (the good bits)
};

var myObject = { key: "value", a: "b", id: "theId" };
var myClone = clone(myObject, "id");

console.log(myClone);
Jacob Lockwood
  • 380
  • 1
  • 12
  • Thank you Jacob, do you know if JSON.parse or the Object.assign solution can exclude a property? I have one property, the Id, that I assign in the database. thank you again. – SkyeBoniwell Apr 29 '21 at 23:21
  • 1
    This is a funny coincidence. I was just searching for this exact problem, which is how I found this solution. There are some great solutions [here](https://stackoverflow.com/questions/34698905/how-can-i-clone-a-javascript-object-except-for-one-key). I will add one to my post right now. – Jacob Lockwood Apr 29 '21 at 23:24
  • That looks nice! What is `ignore` is that a property? So when you pass in `id` it will ignore the property with the name, `id`? thanks! – SkyeBoniwell Apr 29 '21 at 23:34
  • 1
    `...ignore` is a [`rest parameter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). So you can pass as many keys to `clone()` as you want, and they will be interpreted as an array called ignore, which can be iterated using a `for...of` loop. – Jacob Lockwood Apr 29 '21 at 23:41