-1

I'm trying to create a function called maybeNoises to test if an array has noises or not and then to print them to the console.

The prompt is as follow:

Function should take an object, if this object has a noises array return them as a string separated by a space, if there are no noises return 'there are no noises' (2, 1, 3)

This is my code:

function maybeNoises(object) {
  if (object.noises) {
    return object.noises.join(" ");
  } else if (object["noises"].isArray(undefined)) {
    console.log("THIS TEST IS STUPID AND PISSING ME OFF");
  } else(object["noises"].isArray(null));
  return 'there are no noises';
}

This is what it is testing:

QUnit.test("maybeNoises() : Should take an object, if this object has a noises array return them as a string separated by a space, if there are no noises return 'there are no noises'",

function(assert) {
  assert.equal(maybeNoises({
    noises: ["bark", "woof", "squeak", "growl"]
  }), "bark woof squeak growl");
  assert.equal(maybeNoises({
    noises: []
  }), "there are no noises");
  assert.equal(maybeNoises({}), "there are no noises");
});

What am I doing wrong?

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
Ashton
  • 63
  • 7
  • 2
    `object["noises"].isArray(undefined)` what the heck is this supposed to be doing – Jaromanda X Nov 10 '17 at 01:46
  • 1
    an Array does not have a `.isArray` property ... you're thinking of `Array.isArray(object.noises)` – Jaromanda X Nov 10 '17 at 01:48
  • I put object["noises"].isArray(undefined) to test the condition for an empty array. I'm assuming I didn't do it right in regard to your wording expression. – Ashton Nov 10 '17 at 01:50
  • an empty Array is tested by `object.noises.length === 0` once `object.noises` has been determined to be an Array – Jaromanda X Nov 10 '17 at 01:51
  • `else(object["noises"].isArray(null));` isn't valid javascript syntax either – Jaromanda X Nov 10 '17 at 01:55
  • function-master.js:113 Uncaught TypeError: Cannot read property 'length' of undefined at maybeNoises (function-master.js:113) at Object. (function-master.html?notrycatch:77) at Test.run (qunit-1.19.0.js:804) at qunit-1.19.0.js:942 at process (qunit-1.19.0.js:624) at begin (qunit-1.19.0.js:606) at qunit-1.19.0.js:666 – Ashton Nov 10 '17 at 01:55
  • that's the error message I get when I set the expression to test against object.noises.length ===0 – Ashton Nov 10 '17 at 01:56
  • what is `object` when you get that error? your whole logic is reverse order to what it should be – Jaromanda X Nov 10 '17 at 01:56
  • Object is undefined – Ashton Nov 10 '17 at 01:58
  • Well I'm trying to get the logic down. What it is that I'm actually suppose to be doing if I'm doing completely the opposite. – Ashton Nov 10 '17 at 01:59
  • if object is `undefined` then of course it doesn't have a property called length – Jaromanda X Nov 10 '17 at 02:03
  • `const maybeNoises = object => Array.isArray(object.noises) && object.noises.join(' ') || 'there are no noises';` – Thomas Nov 10 '17 at 02:57

2 Answers2

1

The issues with your code are

  1. else(object["noises"].isArray(null)) isn't valid syntax
  2. if (object.noises) return object.noises.join(" "); - your first test assumes that object has a property named noises, and that this noises object has a property called join which is a function ... that's a lot to assume without testing!!! ... what if noises is true for example, true doesn't have a join property! What if object is null/undefined? It doesn't even have a property called noises!
  3. object["noises"].isArray(undefined) an array doesn't have a isArray function, only Array (literally, Array, not "an Array") has that function, and the argument to it should be the object you want to test

So, here's all you need to do

function maybeNoises(object) {
// we know nothing about object yet, so lets not assume
    if (object && object.noises) { // check that object and object.noises are "something"
        // here, we know that object.noises is "something" 
        if (Array.isArray(object.noises)) { // check that object.noises is an Array
            // here we know that object.noises is an array, so, it has a length
            if (object.noises.length > 0) { // check length is > 0
                return object.noises.join(' ');
            }
        }
    }
    return 'there are no noises'; // didn't pass the above tests, so return this string
}
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • *"`else(object["noises"].isArray(null))` isn't valid syntax"* - Sure it is. It just doesn't do at all what the OP wants. – nnnnnn Nov 10 '17 at 02:33
  • yeah, that @nnnnnn :p – Jaromanda X Nov 10 '17 at 02:42
  • You're psuedocode helped a lot. I understand now more how I should have approached the issue and where my flawed logic was, which is what I wanted more than the answer. I'm a total coding newb so all these concepts kinda assaulted me at once and I have trouble navigating through it a bit. Thank you for explaining it to me. – Ashton Nov 10 '17 at 06:56
  • that's not psuedocode, that's how you should actually re-write your code – Jaromanda X Nov 10 '17 at 08:20
0

I edited my answer to summarize all the problems:

1.) Check if there is a noises array.

You wanna do Array.isArray(object.noises) or if you are in the unlikely event of this not working in your javascript implementation you can check for other alternatives here: Check if object is array?

2.) Check if the array has elements: object.noises.length can be used to see if the array has any entries.

3.) Return the noises as array You figured that out already correctly.

Stefan Lindblad
  • 410
  • 2
  • 17
  • `A proper test` - would be `Array.isArray(object.noises)` since about 2010 (even IE9) – Jaromanda X Nov 10 '17 at 01:50
  • Yes that alternative is also listed in the linked answers. But it wouldnt work with `undefined` as argument ;) – Stefan Lindblad Nov 10 '17 at 01:51
  • really? so `Array.isArray(undefined)` does what? – Jaromanda X Nov 10 '17 at 01:56
  • I know. I updated my answer to clearify the different options. – Stefan Lindblad Nov 10 '17 at 01:59
  • I already know it's an array. What is not passing, is that I have a second test that is testing against an empty array (undefined) and I am trying to put an appropriate else if statement to test against that. – Ashton Nov 10 '17 at 02:00
  • What do you wanna test with isArray(undefined) the isArray function does not take any arguments. Check the documentation of it here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray – Stefan Lindblad Nov 10 '17 at 02:02