Javascript Reference Error - not defined

Falc410

Vice Admiral
Registriert
Juni 2006
Beiträge
6.664
Ich bin ein totaler Javascript Anfänger was Javascript angeht und versuche gerade einen REST Service abzufragen und habe dazu ein Tutorial gefunden welches mit Knockout.js arbeitet. Da wurde gezeigt wie man per REST eine JSON Liste abruft und darstellt. Nun wollte ich das erweitern und zusätzlich eine zweite Abfrage mache bei der ich keine Liste erhalte sondern ein einzelnes Objekt mit mehreren Attributen.

Allerdings habe ich wie gesagt keinen Plan davon und erst mal die Methode aus dem Tutorial kopiert, das ist die self.ajax. Weiter unten rufe ich dann nocheinmal self.ajax auf und bekomme das Ergebnis im data Objekt. Das enthält also mein JSON Objekt mit den ganzen Attributen. Nun möchte ich einen Teil der Attribute meinen Variablen zuweisen und diese dann als knockout observable deklarieren da diese weiter oben im HTML Code ein Data-Binding haben. Das funktioniert hier in dem Beispiel auch mit dem Namen aber die Punkte gehen nicht. Firebug zeigt mir dann an den Reference Error an und sagt das points nicht defined ist - name geht aber. Das verstehe ich nicht. Klar ich definier die Variable innerhalb einer Funktion aber solange ich nicht var davor schreibe, sollte die doch trotzdem global sein, oder? Und warum funktioniert name? Das kommt sonst auch nirgendwo anders vor.

Code:
function PlayerViewModel() {
        var self = this;
        self.playerURI = 'http://localhost:5000/todo/api/v1.0/player';
        self.username = "test";
        self.password = "test";

        self.ajax = function(uri, method, data) {
            var request = {
                url: uri,
                type: method,
                contentType: "application/json",
                accepts: "application/json",
                cache: false,
                dataType: 'json',
                data: JSON.stringify(data),
                beforeSend: function (xhr) {
                    xhr.setRequestHeader("Authorization",
                            "Basic " + btoa(self.username + ":" + self.password));
                },
                error: function(jqXHR) {
                    console.log("ajax error " + jqXHR.status);
                }
            };
            return $.ajax(request);
        }

        self.ajax(self.playerURI, 'GET').done(function(data) {            
            name = data.player.name
            points = data.player.totalPropertyPoints
            });

        playername = ko.observable(name)
        playerpoints = ko.observable(points)

Also Zeile 28 geht, Zeile 29 nicht mehr. Why?
 
Zuletzt bearbeitet:
Hallo,

ich selbst bin kein Java-Programmierer /-skripter, somit ist mir die Syntax nicht geläufig.

Könnte es dennoch sein, dass Zeile 28 und 29 mit einem Semikolon abgeschlossen werden müssen (was bei Dir fehlt?) ? Wie gesagt - ist meinerseits nur eine Vermutung / Schuss ins Blaue ;)
 
Ich habe selber keine Ahnung wann man ein Semikolon braucht und wann nicht. Bin zur Zeit viel in Python unterwegs, daher vergesse ich das mal ganz gerne, aber in dem Fall macht es keinen Unterschied.

Ich habe noch ein wenig herumexperimentiert - vielleicht kann ich ja einfach nicht mehrere Variablen zuweisen innerhalb einer Funktion, also wollte ich das JSON Objekt zwischenspeichern und spaeter wieder auseinander nehmen, aber das geht auch nicht. Jetzt erkennt er es nur noch als [Object object] und kanns gar nicht parsen. sigh
 
Die Fehlermeldung sagt es doch. Du verwendest etwas das nich deklariert wurde. In dem Skript wird scheinbar jQuery verwendet. Hast du das geladen?

@SonyXP
Keine Ahnung haben aber hauptsache posten oder wie?
JavaScript und Java haben nichts gemeinsam.
 
Meinen JS Kenntnissen nach muss ich Variablen doch nicht deklarieren. Ist ja auch nicht Typ-sicher wie C# z.B. wo ich sage int X. Normalerweise kann ich einfach schreiben var X und falls ich das var weglasse dann sollte es eine globale Variable sein. Das habe ich mit Google herausgefunden.

Obwohl name auch nicht anders verwendet wird wie points scheint es sich hier aber um eine Standard Variable zu handeln - Firebug zeigt mir diese auch auch an, selbst wenn ich alle Einträge von name in meinem Dokument lösche. Deswegen ist wohl doch schon deklariert - aber wenn ich die Variable nicht nur innerhalb dieser Funktion sondern Global benutzen will wie deklariere ich die dann? Ausserhalb von einer Funktion mit var points? Muss ich dann noch einen Wert zuweisen wie var points = "" ?
 
Das ist soweit auch richtig trotzdem kannst du nicht auf ein Objekt zugreifen das noch nicht erzeugt wurde
 
Also woran liegt es dann, dass ich auf name ausserhalb der Funktion zugreifen kann, auf points aber nicht?

Code:
 self.ajax(self.playerURI, 'GET').done(function(data) {
name = data.player.name
points = data.player.totalPropertyPoints
});

Bei diesem Beispiel hier. Oder wie deklarier ich die Variable dann ausserhalb? Hab einiges rumprobiert aber wollte nicht hinhauen. Im Moment hab ich es ganz anders gemacht, aber brauche das fuer die Zukunft - gibts da so Best Practices?
 
Globale Variablen gehören schon mal nicht zu den best practices. Ansonsten kannst du sie auf dem window anlegen. Name sollte das hier sein. Ansonsten könnte aber auch ein closure vorliegen. Ist ohne kompletten Quelltext nicht zu sagen.
 
Eigentlich sollte in der Fehlermeldung genau stehen wo was fehlt. Und sonst gehe einfach mit dem Debugger (z.B. dem vom Firebug) durch den Code und gucke die Werte der Variablen an. Dabei musst du natürlich beachten, dass der Ajax-Request asynchron ist und die Werte nicht sofort da sind.

Mit "var <name>" Deklarierst du eine Variable im aktuellen Scope und in JS haben nur Funktionen einen Scope. Wenn du dich nicht in einer Funktion befindest, dann wird der globale Scope (das window-Objekt) verwendet... das war die Kurzform.
Und auf implizit erzeugte globale Variablen sollte man sich nie verlassen, das ist ein Design-Fehler in JS.
Wenn du z.B. auf "name" zugreifst, bevor der Ajax-Request fertig ist, dann gibt es einen Error, denn die Globale Variable existiert überhaupt nicht. Sie wird erst in dem Callback der "done" Funktion erzeugt (deklariert)...

Ein großes Framework wie Knockout zu verwenden, ohne die Basics vernünftig drauf zu haben, halte ich aber für etwas Zeitverschwendung, denn das ist schon sehr komplexer Kram und auch geübte Köpfe brauchen da viele Stunden zum einarbeiten.
 

Ähnliche Themen

Zurück
Oben