Как правильно обрабатывать объекты json c помощью json.Parse()?

272
19 декабря 2021, 03:20

Имею такой код на HTML странице:

....
ws.onmessage=function(e){
    temp = JSON.parse(e.data);};
...

Периодически на страницу поступают json данные. Пример данных: {"r":1,"s":1}, {"r":5,"s":0}, {"temp_air":"25 °C"}, {"humi_air":"50 %"} и т.п. Когда поступает строка вида {"r":5,"s":0} требуется выполнять функцию установки или удаления атрибута объектов на странице, где relay_id это значение ключа r, а status это значение ключа s.

function changeStateRelay(relay_id, status) {
    if (status == 1) {
        document.querySelector('#relay'+relay_id).setAttribute("checked", "checked");}
    if (status == 0) {
        document.querySelector('#relay'+relay_id).removeAttribute("checked");}
}

а когда поступает строка вида {"humi_air":"50 %"} требуется подставить значение в определенные поля используя document.getElementById(key).innerText = value; , где key это ключ temp_air или humi_air или другого, а value это значение этих ключей.

Когда данные были только вида {"r":1,"s":1},..,{"r":5,"s":0} я использовал код который замечательно работал:

ws.onmessage=function(e){
    temp = JSON.parse(e.data);
    changeStateRelay(temp.r, temp.s);
    }
function changeStateRelay(relay_id, status) {
    if (status == 1) {
        document.querySelector('#relay'+relay_id).setAttribute("checked", "checked");}
    if (status == 0) {
        document.querySelector('#relay'+relay_id).removeAttribute("checked");}
}

для данных вида {"temp_air":"25 °C"},..., {"humi_air":"50 %"} я начал использовать код:

ws.onmessage=function(e){
    temp = JSON.parse(e.data, function(key, value){
            document.getElementById(key).innerText = value});
}

Как объединить эти два способа в один?

Answer 1

Желательно генерировать данные с указанием типа например

{
    "type": "type_first",
    "data": {...}
 } 

После получения обрабатывать их уже в соответствии с указанным типом, например:

if(response.type == 'type_first') 
    typeFirstHandler(response.data)
else if(response.type == 'type_second') 
    typeSecondHandler(response.data)

То есть для каждого типа данных пишите обработчик, такой подход избавит вас от проблем когда понадобится расширить функционал обработки ответа.

Также можно не указывать тип и обрабатывать "чистые" данные, например

let temp = JSON.parse(response)
if (typeof temp[0]['r'] != "undefined"){ // если в первом объекте массива есть ключ 'r'
    // ....
} else if(typeof temp[0]['temp_air'] != "undefined") { // если в первом объекте массива есть ключ 'temp_air'
    // ....
}

Второй способ крайне не желателен т.к вся логика обработки данных в одном месте и когда вам придется расширить функционал или что-то переписать то вы столкнетесь с кучей самых различных проблем.

Также к слову на бэкенде в ответе лучше задать заголовок Content-Type: application/json тогда не придется писать JSON.parse(...), данные сразу придут в виде объекта а не строки.

READ ALSO
Неправильно работает drag & drop в vanile js

Неправильно работает drag & drop в vanile js

Некорректно работает drag & drop, помогите найти ошибку или переписать уже существующий кодХотел реализовать это: внутри контейнера генирируются...

102
Компоненты в JavaScript

Компоненты в JavaScript

Всем доброго времени сутокПри изучении столкнулся с такой вот задачей, реализация компонентов в js

97
Некорректный вывод времени JavaScript

Некорректный вывод времени JavaScript

При выводе часов, минут и секунд , от 0 и до 10 данные выводятся одиночными цифрами , то есть 23:12:5 или 23:5:20, а нужно что бы было 23:12:05 или 23:05:20 Как...

97
Как объединить 2 (option) в фильтре чтобы выводилась нужные статьи из бд

Как объединить 2 (option) в фильтре чтобы выводилась нужные статьи из бд

Здравствуйте! Я мало что понимаю в mySQL, но так вышло, что я с ним связался

211