1

So im trying to build a music player using javascript. I created a DAO file for interacting with Web Database using this code:

function MusicDAO()
{
    this.ins = openDatabase('musicDB', '1.0', 'MusicDB', 100 * 1024 * 1024);
    this.lastQueryResults = null;
    this.lastQueryError = null;
    this.openMainTable();

    this.openMainTable = function()
    {
        return this.execute("CREATE TABLE IF NOT EXISTS m_songs (file_id AUTO_INCREMENT, name, location, pic, genre)");
    };

    this.execute = function(query)
    {
        var instance = this;
        instance.ins.transaction(function(tx){
            tx.executeSql(query, [], function(e, results){
                instance.lastQueryResults = results;
            });
        }, function(e){
            console.log("error", e);
            instance.lastQueryError = e;
        });

        return instance.lastQueryResults;
    };

    this.addSong = function(){
        return this.execute("INSERT INTO m_songs" +
            "(name, location, pic, genre)" +
            "VALUES" +
            "('menahem', '/pla', null, 'trance')");
    };
}

and chrome keep shouting about this:

Uncaught TypeError: Object #<MusicDAO> has no method 'openMainTable' 

and im a bit confused.. i cant call a function before the creation inside a function?

Avihay Menahem
  • 238
  • 1
  • 2
  • 13
  • If you would like to know more about what prototype is in JavaScript you may find some useful information here: http://stackoverflow.com/a/16063711/1641941 – HMR Feb 22 '14 at 00:28

3 Answers3

3

Nope. Javascript is an interpreted language, not a compiled one. Since the interpreter hasn't reached the line where you declare the function, that function doesn't exist yet.

Now, that doesn't mean you can't define your functions before you call them. You can; you just can't do it the way you've written it. Here's an example that I hope clarifies things:

function TestFunctions() {
    // Works
    fn();

    try {
        // Does not work
        this.fnFromExpression();
    } catch (ex) {
        console.log('caught exception');
    }

    function fn() {
        console.log('inside fn()');
    }

    this.fnFromExpression = function() {
        console.log('inside fnFromExpression()');
        // do something
    };

    // now it works
    this.fnFromExpression();
}

new TestFunctions();

The console output will be:

inside fn()
caught exception
inside fnFromExpression()
Katie Kilian
  • 6,815
  • 5
  • 41
  • 64
  • 1
    Not entirely true. Function declarations are interpreted before any other code is run. The problem here is that the code is using a function expression and setting it to a variable. That variable isn't set until that statement. – Scott Mermelstein Feb 21 '14 at 19:36
  • 1
    Yes, I was trying to write an example that clarifies that. I'll update this when I get it done. – Katie Kilian Feb 21 '14 at 19:37
2

No, not in that way. You could add those methods to the prototype of MusicDAO and then let MusicDAO() be a constructor function.

jgitter
  • 3,396
  • 1
  • 19
  • 26
2

You could try putting these methods on the prototype:

function MusicDAO()
{
    this.ins = openDatabase('musicDB', '1.0', 'MusicDB', 100 * 1024 * 1024);
    this.lastQueryResults = null;
    this.lastQueryError = null;
    this.openMainTable();    
}

MusicDAO.prototype.openMainTable = function()
{
    return this.execute("CREATE TABLE IF NOT EXISTS m_songs (file_id AUTO_INCREMENT, name, location, pic, genre)");
};

MusicDAO.prototype.execute = function(query)
{
    var instance = this;
    instance.ins.transaction(function(tx){
        tx.executeSql(query, [], function(e, results){
            instance.lastQueryResults = results;
        });
    }, function(e){
        console.log("error", e);
        instance.lastQueryError = e;
    });

    return instance.lastQueryResults;
};

MusicDAO.prototype.addSong = function(){
    return this.execute("INSERT INTO m_songs" +
        "(name, location, pic, genre)" +
        "VALUES" +
        "('menahem', '/pla', null, 'trance')");
};

This nice thing about this is if you create many instances of MuscDAO (which you probably wouldn't), the method is not duplicated in each instance.

Jess
  • 23,901
  • 21
  • 124
  • 145