JavaScript Ajax Rückgabe lässt sich nicht testen

lordg2009

Lt. Commander
Registriert
Apr. 2009
Beiträge
1.503
Hi, folgendes Problem:

Ich bin dabei, einen kleinen Chat zu programmieren. Ich nutzte Server Site Events (SSE) um aller 2 Sekunden neue Nachrichten zu übertragen, das klappt wunderbar. Manchmal ist es notwendig, Nachrichten zwischendurch ein zusätzliches Mal nachzuladen. Zu diesem Zwecke habe ich ein kleines Ajax Skript (siehe weiter unten). Dieses ruft das php script auf, welches eigentlich auf die SSE Anfragen antwortet, nur dass hier die header für SSE nicht mit übergeben werden. Demnach wird die Ausgabe enstprechend verarbeitet.

Folgender Fehler tritt bei der Ausführung auf:
Code:
Uncaught TypeError: Cannot read property 'appendChild' of null
in der Zeile
Code:
document.getElementById('chat_msgs_' + chat_read_channel).appendChild(msg);

Grund hierfür ist die Variable 'chat_read_channel'.
Sie teilt die Nachrichten auf 3 verschiedene Channel auf. Nehme trage ich als id z.B. 'chat_msgs_1' ein, klappt das ganze, ist halt nur nicht mehr dynamisch.

Merkwürdig ist zum Einen, dass die gleiche Konstruktion innerhalb der SSE funktion funktioniert und zum anderen das Verhalten der Variable:
Code:
console.log("'" + chat_read_channel + "'");
wirft '1' aus (oder eben '2', oder '3';
Code:
console.log(typeof(chat_read_channel));
ergibt 'string'

Code:
if('chat_msgs_1' == 'chat_msgs_' + chat_read_channel) {
	console.log('Gleich');
} else {
	console.log('nicht Gleich');
}
ergibt nicht Gleich

Code:
console.log('chat_msgs_1');
console.log('chat_msgs_' + chat_read_channel);
ergibt:
chat_msgs_1
chat_msgs_1

Beide Ausgaben sind vom Typ string.

Woran kann das nur liegen?
Vielen Dank für eure Hilfe

Code:
// Neue Nachrichten einmal per ajax laden
function chat_read_once() {
	var xmlhttp = new XMLHttpRequest();
	xmlhttp.onreadystatechange = function() {
		if (xmlhttp.readyState == 0) {
			document.getElementById("chat_message").value = "Bitte warten";
		}if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
			document.getElementById("chat_message").value = "";
			var chat_read_channel;
			var channel_new_msg = new Array(false, false, false);
			var msg_array = xmlhttp.responseText.split("\n");
			var msg_act_line;
			for(var i = 1; i < msg_array.length; i++) {
				msg_act_line = msg_array[i].split(" ",2)[1];
				if(typeof(msg_act_line) === 'undefined') {
					continue;
				}
				if(msg_act_line.split(",")[0] == 'channel') {
					chat_read_channel = msg_act_line.split(",")[1];
					channel_new_msg[chat_read_channel] = true;
					continue;
				}
				var msg_time = msg_act_line.split(",")[0];
				var msg_username = msg_act_line.split(",")[2].substr(0, msg_act_line.split(",")[1]);
				var msg_content_array = msg_act_line.split(",");
				msg_content_array.shift();
				msg_content_array.shift();
				var msg_content = msg_content_array.join(",");
				msg_content = msg_content.substr(msg_act_line.split(",")[1]);
				var msg = document.createElement('div');
				msg.innerHTML = '<a class="chat_username" href="?link=message&amp;action=write&amp;msg_to=' + msg_username + '">' + msg_username + '</a> <span class="chat_time">' + msg_time + '</span><br><span class="chat_content">' + msg_content + '</span>';
				document.getElementById('chat_msgs_' + chat_read_channel).appendChild(msg);
				if(document.getElementById('chat_autoscroll_' + chat_read_channel).checked === true) {
					chat_scroll_bottom(chat_read_channel);
				}
			}
		}
	};
	xmlhttp.open("GET", '?link=chat_stream', true);
	xmlhttp.send();
}
 
Definitiv, wenn ich es manuell eintrage (getElementById('chat_msgs_1')) funktioniert es.

Irgendetwas stimmt da nicht. Wie kann es sein, dass 'chat_msgs_1' ungleich 'chat_msgs_' + chat_read_channel ist, wenn die Ausgabe von beiden exakt die gleiche ist (über console.log()), der Typ von beiden String ist? Ich verstehe es nicht. :(
 
Welchen Browser benutzt du? In Chrome kannst du im Javascript-Debugger (F12, dann Sources) Breakpoints setzen, Durchsteppen und dir die Variablen angucken.

Was mir aufgefallen ist: chat_read_channel wird nur initialisiert, wenn

Code:
if(msg_act_line.split(",")[0] == 'channel')

aber in der nächsten Zeile steht:

Code:
var msg_time = msg_act_line.split(",")[0];

Einmal soll es der String 'channel' sein und einmal der Zeitpunkt der Nachricht. Eins kann nur stimmen.

Edit: nehme alles zurück, ich hab das continue übersehen. Bist du dir sicher, dass chat_read_channel '1' ist? Oder sind da vielleicht noch Leerzeichen mit drin?
 
Zuletzt bearbeitet:
Ich lass mich mal nicht über dne Code aus ^^, eine Nutzung von jquery wäre z. B. Ratsam :)

Aber er sagt dir doch was sein Problem ist, es ist eben nicht IMMER ein String. Sondern null, das wird wohl an deiner Abfrage liegen.

if(typeof(msg_act_line) === 'undefined') {
continue;
}

Du prüfst auf undefined aber nicht auf NULL, das sind zwei verschiedene Sachen.

kurzes Beispiel :

var x = null;

x === undefined : false
x === null : true

x == undefined : true
x == null : true
 
Zuletzt bearbeitet:
Sorry für den Code. Ich bin noch neu und anscheinend nicht besonders gut. Ratschläge höre ich mir aber gerne an.

Den Tip mit der Null habe ich versucht, es hat aber nicht geklappt. Ich habe oben auf null oder 'undefined' geprüft. Keine Änderung. Ich dachte die Fehlermeldung würde bedeuten, dass 'document.getElementById('chat_msgs_' + chat_read_channel)' bereits null wiedergibt, da er es nicht gefunden hat und daher '.appendChild(msg)' gar nicht ausgeführt werden kann.
 
Wir haben alle mal angefangen :) Jquery ist super, wen ndu dir das mal anschauen möchtest aber das ja nen anderes Thema.

Jo das ja auch richtig was gibt er dir denn in Zeile 32 mit console.log ( "#" + chat_read_channel) aus, da wird einmal nul lstehen richtig ?
 
Ne, das gibt #1 aus, wie gewollt.
Ergänzung ()

Hab deine Funktion noch mal erweitert, um meiner Problematik Nachdruck zu verleihen:

Code:
console.log ( "chat_msgs_" + chat_read_channel + " " + typeof(chat_read_channel));
if("chat_msgs_1" == "chat_msgs_" + chat_read_channel) {
	console.log("gleich"); 
} else { 
	console.log("nicht gleich"); 
}

Ausgabe:
Code:
chat_msgs_1 string
nicht gleich
 
Also irgendwas kan nbei dir ja da nicht stimmen entweder das Element exestiert nicht im DOM oder deine Variable enthält nicht ne Zahl.

Setze mal readchannel auf 1 was passiert dann

Ich habs mal kurz getestet also funktionieren tut es. Hätte an typenumwandlung gedacht, aber das funktioniert bei dir ja wie es scheint

console.log ( "chat_msgs_" + chat_read_channel + " " + typeof(chat_read_channel));
if("chat_msgs_1" == "chat_msgs_" + chat_read_channel) {
console.log("gleich");
} else {
console.log("nicht gleich");
}

liefert bei mir "gleich" so wie es sein soll.
 
Zuletzt bearbeitet:
Ich hab des Rätsels Lösung gefunden:

Sooooooo ärgerlich. :(

Bei der Ausgabe von SSEs beginnt jede Zeile mit einem data: und endet mit einem EOL

Bei der Auswertung der SSEs machte dass kein Problem, da sich das Event Object darum kümmert.

Bei der manuellen Datenanpassung ist es anders.
Ein simples ändern der Zeile 19 von
Code:
chat_read_channel = msg_act_line.split(",")[1];
in
Code:
chat_read_channel = msg_act_line.split(",")[1].substr(0,1);
brachte den Erfolg

Danke für eure Hilfe
Leider stellt weder die Chrome noch firefox Konsole Zeilenumbrüche am Ende der Zeile dar.
 
Oha . Okay daran hätte ich jetzt nicht gedacht :D aber klar Steuerzeichen im String, dann sind se bei dir natürlich auch nicht gleich.

Dachte schon ick bin blöde....
 
Zurück
Oben