Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Обработка JSON. Uncaught TypeError: Cannot read property 'xdata' of undefined (https://javascript.ru/forum/misc/49648-obrabotka-json-uncaught-typeerror-cannot-read-property-%27xdata%27-undefined.html)

anton.fed 22.08.2014 13:51

Обработка JSON. Uncaught TypeError: Cannot read property 'xdata' of undefined
 
Имеется JSON:
{
	"elements": {
		"group": {
			"tmpl": "tmpl-group",
			"params": [{
				"name": "main1",
				"values": ["a", "b"]
			}, {
				"name": "label1",
				"value": "id",
				"readonly": true

			}]
		},
		"el": {
			"tmpl": "tmpl-el",
			"params": [{
				"name": "main1",
				"values": ["a", "b"]
			}, {
				"name": "label1",
				"value": "id",
				"readonly": true
			}, {
				"name": "text1",
				"defvalue": ""
			}]
		}
	},
	"xdata": [{
		"id": 44,
		"type": "group",
		"paramvalues": ["a"],
		"children": [{
			"id": 14,
			"type": "el",
			"paramvalues": ["b", "name1"]
		}]
	}, {
		"id": 38,
		"type": "el",
		"paramvalues": ["a", "name2"]
	}]
}


Пытаюсь создать новый объект из ветки xdata так, чтоб занести описание типов из ветки elements (это типы) в дерево элементов в xdata. Но когда хочу получить ветку из JSON вылетает ошибка Uncaught TypeError: Cannot read property 'xdata' of undefined. Как будто не задано свойство this.loadedJSON.

Это только в хроме. В FF через debugger firebug-a проверял - все срабатывает без ошибок.

Вот на скрине дебаггер с результирующим объектом


function myobj() {
	this.loadedJSON;
	this.objtree;
};

myobj.prototype.loadJSON = function() 
{
	var that = this;
	$.getJSON('json/test.json', function(data) {
		that.loadedJSON = data;
	}).fail(function() {
		console.log("Ошибка JSON")
	});

	return this.loadedJSON;
}
myobj.prototype.prepareJSON = function() 
{
	var json = this.loadedJSON;
	var x = json.xdata; // Uncaught TypeError: Cannot read property 'xdata' of undefined 
	var y = json.elements;

	function cc(obj) {
		var accum = [];
		for (var i = 0; i < obj.length; i++) {
			accum[i] = jQuery.extend(true, {}, obj[i]);
			accum[i].index = i;
			accum[i].t = jQuery.extend(true, {}, y[obj[i].type].params);
			accum[i].tmpl = y[obj[i].type].tmpl.toString();
			if (obj[i].children)
				accum[i].children = cc(obj[i].children);
		}
		return accum;
	};
	this.objtree = cc(x);
}
x = new ft();
x.loadJSON();
x.prepareJSON();


Возможно код не очень адекватный, но я только учусь )

tsigel 22.08.2014 13:55

anton.fed,
Не надо методы и ключи объекта называть одним именем, вы потеряете доступ к методу.

anton.fed 22.08.2014 14:45

tsigel,
Поясните, какие именно ключи и методы?

skrudjmakdak 22.08.2014 15:18

напишите console.log здесь и скажите, что у вас вышло:
var json = this.loadedJSON;
console.log(json);
var x = json.xdata; // Uncaught TypeError: Cannot read property 'xdata' of

anton.fed 22.08.2014 15:29

skrudjmakdak,
Пишет undefined
Хотя если поставить точку останова в дебагере как на скрине выше (на строке x.prepareJSON(); ) и сразу же продолжить выполнение ( F10), то в консоли выводит JSON объект из файла. В хроме не срабатывает никак
Хром:

skrudjmakdak 22.08.2014 15:33

вот, в this.prepareJSON у вас undefined. зайдите в network(в хроме так вкладка называется) найдите ваш запрос по адресу "json/test.json" и кликнете по нему, справа у вас появится несколько вкладок: headers, preview, response, cookies. зайдите во вкладку response и посмотрите что у вас там. это должен быть ответ от сервера

anton.fed 22.08.2014 15:37

Посмотрел дебаггером в хроме, свойство this.loadedJSON = undefined после выполнения функции loadJSON.
Получается код работает только в одном случае, если в Firefox-е в дебагере остановить выполнение перед этой функцией.

В любом случае я чтото делаю не так. Посдкажите как правильно получить объект из json файла и обработать его.

anton.fed 22.08.2014 15:39

skrudjmakdak,
в Response содержимое файла json/test.json, т.е. он загружается корректно

skrudjmakdak 22.08.2014 15:41

вы помоему не правильно аякс запрос прописали посм здесь:
http://api.jquery.com/jquery.getjson/
var jqxhr = $.getJSON( "example.json", function() {
  console.log( "success" );
})
  .done(function() {
    console.log( "second success" );
  })
  .fail(function() {
    console.log( "error" );
  })
  .always(function() {
    console.log( "complete" );
  });
 
// Perform other work here ...
 
// Set another completion function for the request above
jqxhr.complete(function() {
  consol
e.log( "second complete" );
});

skrudjmakdak 22.08.2014 15:42

хотя подождите, пропишите еще так:
$.getJSON('json/test.json', function(data) {
console.log(data);
        that.loadedJSON = data;
    }).fail(function() {


имхо не хватает метода done

anton.fed 22.08.2014 15:48

Цитата:

Сообщение от skrudjmakdak
хотя подождите, пропишите еще так:
1 $.getJSON('json/test.json', function(data) {
2 console.log(data);
3 that.loadedJSON = data;
4 }).fail(function() {


имхо не хватает метода done

в консоль вывелся json объект

сделал вывод через done
myobj.prototype.loadJSON = function() 
{
	var that = this;
	$.getJSON('json/test.json')
	.done(function(data){
		console.log(data);
		that.loadedJSON = data;
	})
	.fail(function() {
		console.log("Ошибка обработки JSON")
	});

	//return this.loadedJSON;
}

Все то же самое - ошибка в той же строке : Uncaught TypeError: Cannot read property 'xdata' of undefined

WorM32 22.08.2014 15:50

Вот нагородили-то )

Естесно он будет undefined, тк ваш запрос не успевает завершиться, а вы уже запрашиваете результат в следующей строке.

skrudjmakdak 22.08.2014 15:51

чудеса, да и только. можете кинуть ваше творение полностью, хочу посмотреть

skrudjmakdak 22.08.2014 15:52

WorM32,
точняк))) чет под вечер туплю

anton.fed 22.08.2014 15:52

WorM32,
Подскажите как сделать тогда.

skrudjmakdak 22.08.2014 15:56

как то так))
$.getJSON('json/test.json', function(data) {
        that.loadedJSON = data;
that.prepareJSON();
    }).fail(function() {

WorM32 22.08.2014 16:01

anton.fed,
уже подсказали один из вариантов)

anton.fed 22.08.2014 16:18

Цитата:

Сообщение от skrudjmakdak (Сообщение 327103)
как то так))
$.getJSON('json/test.json', function(data) {
        that.loadedJSON = data;
that.prepareJSON();
    }).fail(function() {

да так работает Спасибо!
Но как теперь мне обращаться к объекту если он не успевает загрузить JSON
тут например консоль покажет undefined , т.к. json еще не загрузился.
x = new myobj();
x.loadJSON();
console.log(JSON.stringify(x.xdata,null,'  '));
/**/


как тут быть?

skrudjmakdak 22.08.2014 16:23

можно сделать функцию обратного вызова:
....
myobj.prototype.loadJSON = function(callback) 
{
	var that = this;
	$.getJSON('json/test.json', function(data) {
		that.loadedJSON = data;
		that.prepareJSON();
if (typeof callback == 'function')
	callback(that, true);
	}).fail(function() {
		console.log("Ошибка JSON");
if (typeof callback == 'function')
	callback(that, false);
	});

	return this.loadedJSON;
}
......
x = new ft();
x.loadJSON(function (obj, success) {
//actions
});

anton.fed 22.08.2014 17:02

Если так:
x.loadJSON(function (obj, success) {
//actions
});

то получается x.loadJSON - это можно сказать инициалиация объекта, все действия с объектом загруженным из json я смогу делать только внутри этой функции?


Часовой пояс GMT +3, время: 05:36.