0

I am making a website where you put a time of the day in, and it searches for a verse with that reference through the whole bible. For instance, if I put in 5:12, it would search through random books of the bible until it found a verse with the reference 5:12. ex: Psalms 5:12. Or at least that is how it is supposed to work. I have a loop that is supposed to find if that verse is not in a specific book, and if it is not, it goes on to the next book. That loop is not working.

bookList = Object.getOwnPropertyNames(esvJSON)

randBook = bookList[Object.keys(bookList)[Math.floor(Math.random() * 
66)]];
inputVerse = esvJSON[randBook][input1];

Object.size = function(obj) {
    var bookLength = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) bookLength++;
    }
    return bookLength;
};

// Get the size of an object
var bookLength = Object.size(inputVerse);

verseIndex = ["01","1", 
"2","3","4","5","6","7","8","9","10","11","12",]
var varBoolean = true;
var i = 0;;

while (varBoolean == true) {
    if (input1 > bookLength) {
        i++;
        randBook = bookList[Object.keys(bookList) . 
[Math.floor(Math.random() * 66)]];
    }
    else if (esvJSON[randBook][input1][input2] == undefined) {
        i++;
        randBook = bookList[Object.keys(bookList) . 
[Math.floor(Math.random() * 66)]];
    }
    else {
        bibleVerse = esvJSON[randBook][input1][input2];
        output = randBook + " " + input1 + ":" + input2 + " " + 
bibleVerse;
        varBoolean = false;
    }
    if (i > 66) {
        varBoolean = false;
        output = "Sorry, we have no verse for your time."
    }
}

It works fine if "Genesis" has the reference 5:12, but if "James" doesn't have 5:12, it automatically either resorts to a "Cannot read property of undefined" error, or it outputs, "Sorry, we have no verse for that time." That should only be the output, when none of the books of the bible have that verse. ex 17:135 should output the sorry message. Most of it is working. I tried to fix it by calling a new book underneath the "i++" but that didn't fix the problem.

The website is actually online, so if you want to test it for yourselves you can go to http://calebdidthis.com/timeverse

Edit:

I made some changes, and I no longer get errors, but I do get the "sorry message" when it should be cycling through books

var varBoolean = true;
var i = 0;;

while (varBoolean == true) {
    bookList = Object.getOwnPropertyNames(esvJSON);
    randBook = bookList[Object.keys(bookList)[Math.floor(Math.random() 
* 66)]];
    inputVerse = esvJSON[randBook][input1];

Object.size = function(obj) {
    var bookLength = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) bookLength++;
    }
    return bookLength;
};

// Get the size of an object
var bookLength = Object.size(inputVerse);



if (input1 >= bookLength) {
    i++;
    //randBook = bookList[Object.keys(bookList)[Math.floor(Math.random() * 66)]];
}
else if (esvJSON[randBook][input1][input2] == undefined) {
    i++;
    //randBook = bookList[Object.keys(bookList)[Math.floor(Math.random() * 66)]];
}
else {
    bibleVerse = esvJSON[randBook][input1][input2];
    output = randBook + " " + input1 + ":" + input2 + " " + bibleVerse;
    varBoolean = false;
}
if (i > 66) {
    varBoolean = false;
    output = "Sorry, we have no verse for your time."
    }
}
Caleb
  • 21
  • 5
  • Looks like you haven't checked whether `input1` is a valid index in `esvJSON[randBook]` – Robin Zigmond Jan 31 '19 at 12:38
  • input1 was only giving me problems when it was larger than the amount of chapters in a given book, and `if (input1 > bookLength)` solved that for the most part – Caleb Jan 31 '19 at 12:40
  • Sorry, I'd missed that. But it's not correct, because indexes only go up to 1 less than the length - you should be checking for `input1 >= bookLength` – Robin Zigmond Jan 31 '19 at 12:41
  • Actually, that's not the issue anyway. You have `bookLength = Object.size(inputVerse);`, and `inputVerse = esvJSON[randBook][input1];`. So if `input1` is too big you've already hit an error before reaching that point. – Robin Zigmond Jan 31 '19 at 12:42
  • I still get the error sometimes, and I still often get "Sorry, we have no verse for that time." – Caleb Jan 31 '19 at 12:43
  • So how should I fix that? Do I just re order some things? – Caleb Jan 31 '19 at 12:45
  • Having just looked more closely - you're ONLY printing the error message when `i > 66`, and `i` is just a counter variable measuring how many times you've been through the loop. (It does nothing at all inside the loop.) And since you're picking a random book each time through, it's pure chance whether you see the message or not. But for a "fix" to not get that error thrown, I think you need only change the incorrect check `if (input1 > bookLength)` to `if (input1 >= esvJSON[randBook])` - and to do this you need to generate the `randBook` at the top of the loop, before all `if` statements. – Robin Zigmond Jan 31 '19 at 12:51
  • That left inputVerse and bookLength giving errors since randBook wasn't there, so I commented those out, and did what you said, and now every time the verse isn't in a specific book I get an error. And randBook is a variable that finds a random book of the Bible, so I don't think it is doing anything by comparing to input1 – Caleb Jan 31 '19 at 13:01
  • oops, sorry, I meant `if (input1 >= esvJSON[randBook].length)`. I would edit, but SO doesn't let you edit comments if you made them more than 5 minutes ago. And I already mentioned the need to move the definition of `randBook` to the top of the loop. – Robin Zigmond Jan 31 '19 at 13:05
  • Check out the edit to my post. I got some stuff sorted out, but some stuff isn't – Caleb Jan 31 '19 at 13:15
  • Oh blimey, I only just realised from your latest edit, and inspecting the source at : http://calebdidthis.com/esv.js - each "book" in your `esvJSON` is represented not by an array, as I thought, but by an object. I need to think about what this means for your code, I assume you were using arrays (which would be a much more sensible data structure for this). – Robin Zigmond Jan 31 '19 at 13:20
  • Oh, sorry, I forgot to mention that everything is objects, and not arrays, and that I have a huge hulking variable that takes up 33,000 lines :) – Caleb Jan 31 '19 at 13:21
  • 1
    there are a lot of issues in the code, check the answer i have provided a code that should work based on assumptions that input1 and input 2 are what they are supposed to be – AvcS Jan 31 '19 at 13:26
  • So I should swap out my code for what you have down there? I tried that, and I got all kinds of errors. – Caleb Jan 31 '19 at 13:27
  • Oh my gosh, nevermind, it works like a charm, so I might be spending the next 2 hours figuring out how it works – Caleb Jan 31 '19 at 13:29
  • I tried to explain everything, dont mind much about the shuffle logic I copied it too :) – AvcS Jan 31 '19 at 13:31

1 Answers1

0
// Shuffle an array
function shuffle(a) {
    var j, x, i;
    for (i = a.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = a[i]; a[i] = a[j]; a[j] = x;
    }
    return a;
};

// This gives an array of keys in envJSON
bookList = Object.getOwnPropertyNames(esvJSON);

// Shuffle the array of book names as you want to go through all the books, but randomly
// This makes sure none of the books is missed while checking
var shuffledBookList = shuffle(bookList);

// Now just loop through all the books in shuffledBookList
output = null;
for (var i = 0; i < shuffledBookList.length; i++) {
    // Get the random book name from array
    var randomBookName = shuffledBookList[i];

    // Get the actual book using bookname
    randBook = esvJSON[randomBookName];

    // Get the verse at input1 from randBook
    inputVerse = randBook[input1];

    // If the verse exists and verse has a value at input2 process it and break the loop
    if (inputVerse && inputVerse[input2]) {
        bibleVerse = inputVerse[input2];
        output = randomBookName + " " + input1 + ":" + input2 + " " + bibleVerse;
        break;
    }
}

// if output is still null, show the message
if (output === null) {
    output = "Sorry, we have no verse for your time.";
}

Shuffle array logic is taken from here

AvcS
  • 2,263
  • 11
  • 18