Mysterious Organism ( Problem calling .mutate())

Hello there,
I am currently dealing with the Mysterious Organism project and I am facing a problem calling the .mutate() method of an object I made, inside the function pAequorFactory. More precisely, every time I call the function pAequorFactory I get on the debug console this : {specimenNum: 2, dna: Array(15), mutate: ƒ}.

I cannot understand why it’s not giving me the mutated array at mutate on the debug console, but it gives the letter f. If I change my code and replace ‘return object’ at pAequorFactory with ‘return object.mutate()’ I get the right result.

I guess I don’t understand something when it comes to calling an object that is inside a function and contains a method in it. Any insight please?

Thank you for your time, here is my code:

// Returns a random DNA base
const returnRandBase = () => {
  const dnaBases = ['A', 'T', 'C', 'G']
  return dnaBases[Math.floor(Math.random() * 4)] 
}

// Returns a random single stand of DNA containing 15 bases
const mockUpStrand = () => {
  const newStrand = []
  for (let i = 0; i < 15; i++) {
    newStrand.push(returnRandBase())
  }
  return newStrand
}


const pAequorFactory = (number, arrayFunc) =>
{
  const object = 
  {
    specimenNum: number,
    dna: arrayFunc,
    mutate()
    {
      let b = returnRandBase();
      const dnaArray = this.dna; 
      const randomBase = dnaArray[Math.floor(Math.random()*dnaArray.length)];
      for (let i = 0; i < dnaArray.length; i++)
      {
        if (dnaArray[i] === randomBase )
        {
           while (b === randomBase)
          {
            b = returnRandBase()
          };
          dnaArray.splice(i,1,b);
        }
      }
      return dnaArray;
    }
  };
  return object;
};
console.log(pAequorFactory(2,mockUpStrand()));

Here is also the link of the project : https://www.codecademy.com/paths/full-stack-engineer-career-path-21/tracks/fscp-javascript-syntax-part-ii/modules/fecp-challenge-project-mysterious-organism/projects/mysterious-organism#page-skip-to-content-target

I would also like to add something very strange happening. When I use this.dna in the mutate() method, it gives me a different array than the one on the key - value pair dna: arrayFunc.

the result of the pAequorFactory function is an object that has a specimenNum property that’s a number, a dna
property that’s an array and a mutate method (function).
Thus, {specimenNum: 2, dna: Array(15), mutate: ƒ} is what you’d expect when you do console.log for the result of the pAequorFactory function.

What output were you trying to produce?

and .splice changes the original array, but .slice does not.

Because an array is an object,
const dnaArray = this.dna;
does not make a new array; it makes a new reference to the same array in .dna instead.
So when you change the dnaArray array, you also change the array in .dna

Everything you said. concerning the mutate() method are well understood, thank you! About the dna property, the dnaArray and splice, I have some questions. Although I understand that splice changes the original array, the problem is before it. Let me give you first an explanation of what the code does first.

We have a specie that we examine its DNA and the way it mutates. The returnRandBase function, chooses one of the 4 DNA bases (A,T,C,G) randomly. Then, with the mockUpStrand function, we make a random single stand of DNA containing 15 bases (A,T,C,G). After that, I am using the pAequorFactory function to mutate the original strand of DNA, by changing one of the bases with a different letter i.e. change A to T,C or G but not A again.

The dna property contains the array with the DNA strand of 15 bases. And I am putting this specific array on the dnaArray variable using this.dna. Then I mutate the dnaArray variable get the final mutated array.

The problem is that if I run my code, a different array is stored in the dna property and in the variable dnaArray BEFORE the mutation, which I don’t understand!

I did’t see that problem occurring when I tested your code:
.dna and dnaArray was the same at every point.

// Returns a random DNA base const returnRandBase = () => { const dnaBases = ['A', 'T', 'C', 'G'] return dnaBases[Math.floor(Math.random() * 4)] } // Returns a random single stand of DNA containing 15 bases const mockUpStrand = () => { const newStrand = [] for (let i = 0; i < 15; i++) { newStrand.push(returnRandBase()) } return newStrand } const pAequorFactory = (number, arrayFunc) => { const object = { specimenNum: number, dna: arrayFunc, mutate() { console.log(".mutate() function started"); let b = returnRandBase(); const dnaArray = this.dna; console.log("dnaArray = " + dnaArray.join('') ); const randomBase = dnaArray[Math.floor(Math.random()*dnaArray.length)]; for (let i = 0; i < dnaArray.length; i++) { if (dnaArray[i] === randomBase ) { while (b === randomBase) { b = returnRandBase() }; console.log(`at index ${i}, ${dnaArray[i]} changed to ${b}`); dnaArray.splice(i,1,b); } } console.log("dnaArray = " + dnaArray.join('') ); return dnaArray; } }; return object; }; const pAequor2 = pAequorFactory(2,mockUpStrand()); console.log("original .dna = " + pAequor2.dna.join('') ); let returnedFromMutate = pAequor2.mutate(); console.log("array returned by .mutate() is " + returnedFromMutate.join('') ); console.log("current .dna = " + pAequor2.dna.join('') );

So, I might be doing or understanding something wrong again, but please let me show you. Indeed, the way you tested the code gives correct result. But, if you put this line on the code: console.log(pAequorFactory(2,mockUpStrand()));
just above the variable pAequor2 you created, you will see that dna property has a different array. I’ve added it on the code u posted but not sure if you can see it.

Yes, each time you do pAequorFactory(2, mockupStrand()), you’ll get an object that has a different .dna because .mockupStrand() generated a new array each time.
Isn’t that what you want to happen?

// Returns a random DNA base const returnRandBase = () => { const dnaBases = ['A', 'T', 'C', 'G'] return dnaBases[Math.floor(Math.random() * 4)] } // Returns a random single stand of DNA containing 15 bases const mockUpStrand = () => { const newStrand = [] for (let i = 0; i < 15; i++) { newStrand.push(returnRandBase()) } return newStrand } const pAequorFactory = (number, arrayFunc) => { const object = { specimenNum: number, dna: arrayFunc, mutate() { let b = returnRandBase(); const dnaArray = this.dna; const randomBase = dnaArray[Math.floor(Math.random()*dnaArray.length)]; for (let i = 0; i < dnaArray.length; i++) { if (dnaArray[i] === randomBase ) { while (b === randomBase) { b = returnRandBase() }; dnaArray.splice(i,1,b); } } return dnaArray; } }; return object; }; console.log("result1:"); console.log(pAequorFactory(1,mockUpStrand()).dna); console.log("result2:"); console.log(pAequorFactory(2,mockUpStrand()).dna); console.log("result3:"); console.log(pAequorFactory(3,mockUpStrand()).dna);

That’s correct, I understand that. But if I run these, shouldn’t I have the same result from the first two console.log?

console.log(pAequorFactory(2,mockUpStrand()));
console.log(pAequorFactory(2,mockUpStrand()).dna)
console.log(pAequorFactory(2,mockUpStrand()).mutate())

Because If I do it I get different results like this one:

{ specimenNum: 2,
dna:
[ ‘T’, ‘C’, ‘C’, ‘A’, ‘C’, ‘A’, ‘C’, ‘A’, ‘T’, ‘C’, ‘G’, ‘G’, ‘T’, ‘A’, ‘T’ ],
mutate: [Function: mutate] }
[ ‘C’, ‘A’, ‘A’, ‘G’, ‘C’, ‘A’, ‘A’, ‘A’, ‘T’, ‘A’, ‘G’, ‘A’, ‘G’, ‘G’, ‘T’ ]
[ ‘A’, ‘C’, ‘A’, ‘T’, ‘T’, ‘T’, ‘A’, ‘A’, ‘A’, ‘T’, ‘A’, ‘C’, ‘T’, ‘A’, ‘A’ ]

[Done] exited with code=0 in 0.535 seconds

Am I missing something?

You would not have the same result because
pAequorFactory(2,mockUpStrand())
creates a new object with a new randomly generated .dna array each time.

If you’d want to keep using the same object, then you’d have to store that in a variable or something.

details

So you’re doing console.log to 3 different objects, each with its own .dna array, which is different than the others’ .dna:

console.log(pAequorFactory(2,mockUpStrand()));
console.log(pAequorFactory(2,mockUpStrand()));
console.log(pAequorFactory(2,mockUpStrand()));

Oh I think now I get it! So, you basically mean that if I want to access .dna for example after I’ve ran pAequorFactory(2,mockUpStrand()), I have to store the pAequorFactory(2,mockUpStrand()) into a variable, and then access the object’s properties. Like you did here:

const pAequor2 = pAequorFactory(2,mockUpStrand());
console.log("original .dna = " + pAequor2.dna.join('') );
let returnedFromMutate = pAequor2.mutate();
console.log("array returned by .mutate() is " + returnedFromMutate.join('') );
console.log("current .dna = " + pAequor2.dna.join('') );

Else, each time I’ll have a different object, thus different .dna.
Am I correct?

Yes, you got it! :+1:

Thank you soooo much! I don’t know why I got so confused, but now all clear. I appreciate your help a lot!