0

I'm making a webpage that displays a motivational quote based on a "mood keyword".

I have an object with arrays:

const moodList = {
sad: [
    '"Dream as if you\'ll live forever, live as if you\'ll die today." James Dean',
    '"Life is a journey, and if you fall in love with the journey, you will be in love forever." Peter Hagerty',
    '"I\'ve learned that people will forget what you said, people will forget what you did, but people will never forget how you made them feel." Maya Angelou'
],
angry: [
    '"For every minute you remain angry, you give up sixty seconds of peace of mind."Ralph Waldo Emerson',
    '"Speak when you are angry - and you\'ll make the best speech you\'ll ever regret." Laurence J. Peter',
    '"Anger and intolerance are the enemies of correct understanding."Mahatma Gandhi'
]}

and this is the code I'm writing to check the user input against the object with arrays. When there's a match it displays a random motivational quote from that specific array. However if I write an else statement, why only the last array inside the object is being considered?

for (let key in moodList) {
  const moodFeeling = key;
  if (askBar.value.includes(moodFeeling)) {
    for (let i = 0; i <moodList[moodFeeling].length; i += 1) {
      motivQuoteResult.push(moodList[moodFeeling][i]);
      const randomResult = Math.floor(Math.random() * motivQuoteResult.length);
      printToPage(motivQuoteResult[randomResult]);
    }
  } else {
    printToPage('<h3>Try again, I don\'t have that feeling on file</h3>');
  }
}

motivQuoteResult = [];

askBar.value = '';
}
});
Pineda
  • 7,435
  • 3
  • 30
  • 45
Amos
  • 11
  • 3

4 Answers4

0

Im assuming you're checking the user input and the user types something like "sad". Then try this code:

let moodQuotes = moodList[askBar.value];
if(Array.isArray(moodQuotes) && moodQuotes.length) {
    printToPage(moodQuotes[Math.floor(Math.random()*moodQuotes.length)])
}
else {
    ... no quote found do something else
}

if the askbar.value should contain any of the available moods just use this:

let possibleMoods = Object.keys(moodList).filter(mood => askbar.value.indexOf(mood) > -1);
let moodQuotes = possibleMoods.map(mood => moodList[mood]);
if(moodQuotes.length === 0) {
  ... no mood found do something else
}
let possibleQuotes = moodQuotes[Math.random()*possibleQuotes.length];
if(possibleQuotes.length === 0) {
  ... no quotes found for mood, do something else
}
printToPage(possibleQuotes[Math.floor(Math.random()*possibleQuotes.length)])
cyr_x
  • 13,987
  • 2
  • 32
  • 46
0

I think you want to do something else in the loop, if no, you don't even need the loop. And I don't know what you want to do with motivQuoteResult. I just leave it. but actually u don't need to push other array's each elements to new array. Try this code and modify as ur purpose:

var askBarValue = askBar.value;
    var hasMoodOnFile = false;
  for (let key in moodList) {
          const moodFeeling = key;

          var    motivQuoteResult = [];
          if (askBar.value.includes(moodFeeling)) {
                  motivQuoteResult = moodList[moodFeeling];
              var randomResult = Math.floor(Math.random() * motivQuoteResult.length);
              result.innerHTML = motivQuoteResult[randomResult];// call your printToPage function instead
              hasMoodOnFile = true;
          } 
  }
  if(!hasMoodOnFile){
          result.innerHTML = '<h3>Try again, I don\'t have that feeling on file</h3>'; // call your printToPage function instead
  }

This is source code: https://jsfiddle.net/85dxus4z/

mudin
  • 2,672
  • 2
  • 17
  • 45
0

With the way your logic is structured, you will call "printToPage" on each iteration of your loop (either in the "if" branch or the "else" branch). If printToPage is overwriting the contents of a DOM element, then you will only see the effect of the last iteration. There would be many ways to fix this, but one way would be to have a boolean variable (e.g. foundMatch) initialized to false before the loop and set it to true in your "if" statement; get rid of the else; then after the loop: if (!foundMatch) { print your "try again" message}

Ryan Cogswell
  • 75,046
  • 9
  • 218
  • 198
0

For searching you have to use indexOf to see if a lowercased (using toLowerCase) key is included in the lowercased text.

Try and type something like I'm so sad right now! in the example bellow:

const moodList = {
  sad: [
    '"Dream as if you\'ll live forever, live as if you\'ll die today." James Dean',
    '"Life is a journey, and if you fall in love with the journey, you will be in love forever." Peter Hagerty',
    '"I\'ve learned that people will forget what you said, people will forget what you did, but people will never forget how you made them feel." Maya Angelou'
  ],
  angry: [
    '"For every minute you remain angry, you give up sixty seconds of peace of mind."Ralph Waldo Emerson',
    '"Speak when you are angry - and you\'ll make the best speech you\'ll ever regret." Laurence J. Peter',
    '"Anger and intolerance are the enemies of correct understanding."Mahatma Gandhi'
  ]
};


var askBar = prompt("Ask bar:"); // for the sake of this example I'm using prompt

var printToPage = alert; // for the sake of this example I'm using alert instead of your printToPage

// to see if we found something or not
var found = false;

for (let key in moodList) {
  // change askBar to askBar.value
  if (askBar.toLowerCase().indexOf(key.toLowerCase()) != -1) {
    var randomIndex = Math.floor(Math.random() * moodList[key].length);
    printToPage(moodList[key][randomIndex]);
    found = true; // we found something
    break; // don't search anymore so terminate the loop
  }
}

// now if we are outside the loop and we've found nothing
if (!found)
  printToPage('Try again! I don\'t have that feeling on file!');
ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
  • This works fantastically! However, why use indexof instead of includes? - I made an example with includes as well and it seems to be doing it? Also - How are you getting to the arrays inside each key. I thought this could only be achieved iterating with a for loop? – Amos Feb 01 '17 at 14:11
  • @Amos I'm just used to using `indexOf` to do searches. Probably `includes` uses it as well. – ibrahim mahrir Feb 01 '17 at 14:13
  • @Amos If you want to know more about the difference check [this](http://stackoverflow.com/questions/35370222/array-prototype-includes-vs-array-prototype-indexof)! – ibrahim mahrir Feb 01 '17 at 14:16
  • @Amos Just saw your other question (_How are you getting to the arrays inside each key. I thought this could only be achieved iterating with a for loop?_). There will be no use to loop through the array just to pick an item. Do it directly by accessing the index you want (the random index we calculate inside the `if` body). – ibrahim mahrir Feb 01 '17 at 14:23
  • Thank you for clarifying it! BTW I found that if I type a feeling in the array and then type a word that isn't in the array I no longer get the "Try again! I don\'t have that feeling on file!" is this because I set the found variable to true? It works with an alert box. Not with an input and a button. – Amos Feb 02 '17 at 19:51
  • @Amos I didn't understand! What do you mean? What's the problem? – ibrahim mahrir Feb 02 '17 at 21:15