Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
über "Fetch" Json Array/Object auswerten
#1
Liebe Forengemeinde,

ich versuche schon die ganze Zeit eine Http request von einer Steckdose mit Tasmota auszuwerten. Über "http://192.168.188.141/cm?cmnd=status%208" sendet die Steckdose die Daten zum Status 8:

{"StatusSNS":{"Time":"2024-01-19T12:58:34","ANALOG":{"Temperature":20.9},"ENERGY":{"TotalStartTime":"2023-12-29T14:09:41","Total":0.009,"Yesterday":0.000,"Today":0.000,"Power":0,"ApparentPower":0,"ReactivePower":0,"Factor":0.00,"Voltage":232,"Current":0.000},"TempUnit":"C"}}

Nun versuchte ich die Daten über:
Code:
            fetch('http://192.168.188.141/cm?cmnd=status%208').then(function(response) {
                response.text().then(function(text) {
                    console.log ("Fetchdaten");
                    console.log (JSON.parse(text));             
                    JSON.parse(text, function (key, value) {
                        if (key == "Time") { document.getElementById('Temp').innerHTML = value; }

                    });
                   /*
                    let lokal = Status.find (lokal => lokal.ENERGY === "Total");
                    console.log ("das ist ein Tset");
                    console.log (lokal);
                    */
                });

auszulesen.
Unter Firefox und dem Entwicklerwerkzeug wird mir angezeigt, die Daten ein/mehrer Object - Daten beinhalten. wie kann ich nun in JS diese Daten so bearbeiten, dass ich sie mir über
Code:
if (key == "ENERGY") document.getElementById('Temp').innerHTML = value;

in meine Webseite holen kann?

Leider kenn ich mich nicht in JS so gut aus und lerne noch...

Vielen DAnk und schönes WE!
MAT
Zitieren
#2
Hallo MAT,
ich hatte bisher noch gar nicht bemerkt, dass JSON.parse als zweiten Parameter eine Callback-Funktion hat. Wenn ich das richtig sehe, ist diese aber mehr dafür gedacht, die Daten umzuarbeiten. Ich würde am Anfang zunächst auf ihre Verwendung verzichten.

Ich habe mal dein Javascript umgeändert, so dass es funktioniert:
Code:
        fetch('thread1245-fetch-javascript-forum.json').then(function (response) {
            // Aus der Antwort vom Server den Text zurück geben:
            return response.text();
        }).then(function (text) {
            // Den Text parsen:
            const parsed = JSON.parse(text);
            // Zeit in DOM-Element anzeigen:
            if (parsed.StatusSNS.Time) {
                console.log(parsed.StatusSNS.Time);
                document.getElementById('Time').innerHTML = parsed.StatusSNS.Time;
            }
            if (parsed.StatusSNS.ENERGY.Total) {
                console.log(parsed.StatusSNS.ENERGY.Total);
                document.getElementById('Total').innerHTML = parsed.StatusSNS.ENERGY.Total;
            }
        });
Die Struktur, die Du vom Server bekommst, besteht aus Objekten und ist mehrfach verschachtelt. Um ein Element darin anzusprechen, musst Du den Objektname, einen Punkt und den Namen des Elementes notieren:
Code:
nameObjekt.nameMember
 Und, da die Objekte in deinem Fall verschachtelt sind, das mehrfach aneinander reihen.

Das Parsen kannst Du übrigen auch einfacher machen:
Code:
fetch('thread1245-fetch-javascript-forum.json').then(function (response) {
            // Aus der Antwort vom Server
            // das geparste JSON zurück geben:
            return response.json();
        }).then(function (parsed) {
            // Jetzt steht das geparste JSON zur Verfügung.
            // Zeit in DOM-Element anzeigen:
            if (parsed.StatusSNS.Time) {            // Zeit in DOM-Element anzeigen:
                if (parsed.StatusSNS.Time) {
                    console.log(parsed.StatusSNS.Time);
                    document.getElementById('Time').innerHTML = parsed.StatusSNS.Time;
                }
                if (parsed.StatusSNS.ENERGY.Total) {
                    console.log(parsed.StatusSNS.ENERGY.Total);
                    document.getElementById('Total').innerHTML = parsed.StatusSNS.ENERGY.Total;
                }
            }
        });
also statt text() json() aufrufen.
Glaube denen, die die Wahrheit suchen, und zweifle an denen, die sie gefunden haben.
(Andrι Gide (1869-1951), frz. Schriftst., 1947 Nobelpreis)
Zitieren
#3
Hallo Sempervivum,

Was soll ich sagen!!! Perfect und gaaanz lieben Dank! Du hast mir den Abend gerettet!
Ich habe den ganzen Tag im Web nach einer Lösung gesucht und zum Glück jetzt hat es geklappt!


Code:
           fetch('http://192.168.188.141/cm?cmnd=status%208').then(function (response) {
            // Aus der Antwort vom Server den Text zurück geben:
                response.text().then(function(text) {
                    console.log ("Fetchdaten");
                    console.log (JSON.parse(text));
                    // Den Text parsen:
                    const parsed = JSON.parse(text);
                    // Zeit in DOM-Element anzeigen:
                    if (parsed.StatusSNS.Time) {
                        console.log(parsed.StatusSNS.Time);
                        document.getElementById('Time').innerHTML = parsed.StatusSNS.Time;
                    }
                    if (parsed.StatusSNS.ENERGY.Total) {
                    console.log(parsed.StatusSNS.ENERGY.Total);
                    document.getElementById('Voltage').innerHTML = parsed.StatusSNS.ENERGY.Voltage;
                    }
                });
            });

Auf die Schnelle habe ich jetzt Deinen Vorschlag etwas abgewandelt und so funktioniert es erst einmal ohne Fehlermelungen. Werde mir aber noch Deine weiteren Hinweise anschauen und durchgehen, nicht mehr heute Wink ! ( das Ur-krostitzer ist schon offen Big Grin )

Was ich noch erreichen möchte:

* habe eine Menge an Tasmota-Steckdosen die ich in der Art auslesen möchte
* gern würde ich die Function so gestallten, dass ich nur eine Function habe und dieser die IP-Adresse übergebe und dann die Daten an eine bestimmten Stelle auf der Webseite anzeige
Das wird bestimmt ne interessante Sache...

Würde mich sehr freuen von Dir eine Unterstützung zu bekommen!

Und nun ist Freitag Abend!
Danke nochmals!
MAT
Zitieren
#4
Zitat:gern würde ich die Function so gestallten, dass ich nur eine Function habe und dieser die IP-Adresse übergebe und dann die Daten an eine bestimmten Stelle auf der Webseite anzeige
Das ist ein guter Plan. Viele gehen her und vervielfachen einfach den Code.

Zitat:Würde mich sehr freuen von Dir eine Unterstützung zu bekommen!
Immer her mit den Fragen.

Beste Grüße und ebenfalls ein schönes Wochenende!
Ulrich
Glaube denen, die die Wahrheit suchen, und zweifle an denen, die sie gefunden haben.
(Andrι Gide (1869-1951), frz. Schriftst., 1947 Nobelpreis)
Zitieren
#5
(19.01.2024, 20:37)Guten Morgen!Sempervivum schrieb:
Zitat:gern würde ich die Function so gestallten, dass ich nur eine Function habe und dieser die IP-Adresse übergebe und dann die Daten an eine bestimmten Stelle auf der Webseite anzeige
Das ist ein guter Plan. Viele gehen her und vervielfachen einfach den Code.

=> Genau, das würde ich auch ersteinmal machen, um zum Erfolg zu kommen. Hier versuche ich mal es anders zu machen.

Zitat:Würde mich sehr freuen von Dir eine Unterstützung zu bekommen!
Immer her mit den Fragen.

=>das hättest Du nicht sagen sollen  Tongue Smile Smile  Würde ich gern in Anspruch nehmen Big Grin


Beste Grüße und ebenfalls ein schönes Wochenende!
Ulrich

=> bei uns scheint gerade echt gut die Sonne und es liegt einwenig Schnee.... gehen heut mal raus und bewegen uns im Wörlitzer Gartenreich Smile
Zitieren
#6
Liebe Mitstreiter,

die letzten Tage einiges gemacht und gelernt und nun hier mein nächstes Problem.

Über einen Button click möchte ich an eine Funktion mehrer Werte schicken, mit id='' und Value='' kann ich mit:
Code:
function myFunction(ele) {
                console.log("Funktion() this");
                console.log(ele.id);
                console.log(ele.value);
               
                fetch(ele.id).then(function(response) {
                    response.text().then(function(text) {
                        JSON.parse(text, function (key, value) {
                            if (key == "Hostname") { document.getElementById("data.value_1").innerHTML = value; }
                            console.log("gesendete daten+");
                            //console.log(document.getElementById('WifiConfigValue' + ele.value).innerHTML = value);
                            if (key == "IPAddress") { document.getElementById("data.value_2" ).innerHTML = value; }   
                        });

                    }); 
                 });
                
            }  
und die Funktion über:
Code:
<button id="http://192.168.188.142/cm?cmnd=status%205" value="Hostname" value_1="dad" onclick="myFunction(this)">Click</button>

anspringen.
Wie kann ich nun mehr als nur 2 "Parameter" per Button Click an eine Funktion übergeben?

Ich suche nach einem Weg, wie ich diese Abfrage mit mehreren "Parameter" für mehrere "id"s lösen kann.
Also 1. id ="http://192.168.188.142/cm?cmnd=status%205"
       2. id= "http://192.168.188.141/cm?cmnd=status%205"
Der Inhalt des " response.text " ist immer der Gleiche:
Code:
{"StatusSNS":{"Time":"2024-01-24T21:36:25","ANALOG":{"Temperature":23.3},"ENERGY":{"TotalStartTime":"2023-12-29T14:15:42","Total":6.246,"Yesterday":1.960,"Today":0.000,"Power":0,"ApparentPower":0,"ReactivePower":0,"Factor":0.00,"Voltage":232,"Current":0.000},"TempUnit":"C"}}

nur die Values sind dementsprechend anders gefüllt.

Also folgender Workflow:

Button click:
 => Fetch: http://192.168.188.142/cm?cmnd=status%205  aufrufen => Daten einsammeln und per { document.getElementById("=2 Parameter=" ).innerHTML = value; }  die 2 Parameter an eine bestimmte Stelle ins HTML schreiben

 => Fetch: http://192.168.188.142/cm?cmnd=status%208  aufrufen => Daten einsammeln und per { document.getElementById("=7 Parameter=" ).innerHTML = value; } die 2 Parameter an eine bestimmte Stelle ins HTML schreiben

..... und das alles für mehrere IP-Adressen.

Soooo wie geh ich nun ran an die Sache..... hat jemand ne Idee?

many THANKS!
MAT
Zitieren
#7
Wenn ich das richtig verstehe, möchtest Du mit einem Buttonclick mehrere fetch-Abfragen ausführen, nicht wahr?

In dem Fall empfehle ich, die Parameter in einem Array abzulegen und dieses bei Buttonclick mit forEach abzuarbeiten, in etwa so:
Code:
const data = [
    {
        url: 'http;//1.2.3.4/cm/usw',
        data2: [
            {key: 'Hostname', idDest: 'dad'},
            {key: 'IPAdress', idDest: 'noch-ne-id'}
        ]
    },
    {
        url: 'http://
usw. mit allen daten, die Du brauchst.

Und dann abarbeiten:
Code:
data.forEach(item => {
    fetch(item.url).then(
// ...
        item.data2.forEach(item2 => {
            document.getElementById(item2[idDest]).innerHTML = dataFromSever[item2.key];
        });
Natürlich ungetestet.
Die Namen "data", "data2" sind etwas pauschal, je nachdem was sich dahinter verbirgt, kannst Du sie ein wenig aussagefähiger machen.
Glaube denen, die die Wahrheit suchen, und zweifle an denen, die sie gefunden haben.
(Andrι Gide (1869-1951), frz. Schriftst., 1947 Nobelpreis)
Zitieren
#8
PS: Mir ist gerade auf gefallen, dass mein Code wahrscheinlich unnötig kompliziert ist. Du schriebst:
Zitat:Der Inhalt des " response.text " ist immer der Gleiche:

Wenn auch immer die selben Elemente aus der Antwort verarbeitet werden sollen, könnte man das so machen:
Die Elemente für die Ausgabe jeweils in einem Container zusammen fassen:
Code:
<div id="cont1">
    <div class="dad"></div>
    <div class="another-class"></div>
</div>

<div id="cont2">
    <div class="dad"></div>
    <div class="another-class"></div>
</div>
Dann brauchst Du nur noch die ID dieses Containers in den Daten:
Code:
const data = [
            {
                url: 'http;//1.2.3.4/cm/usw',
                idCont: 'cont1'
            },
            {
                url: 'http;//4.5.6.7/cm/usw',
                idCont: 'cont2'
            }
        ];

        const data2 = [
            { key: 'Hostname', idDest: 'dad'},
            { key: 'IPAdress', idDest: 'noch-ne-id' }
        ];
Und dann die Auswertung so:
Code:
        data.forEach(item => {
                fetch(item.url).then(
                    // ...
                    const cont =  document.getElementById(item.idCont);
                    data2.forEach(item2 => {
                        const dest = cont.querySelector('.' + item2.classDest);
                        dest.innerHTML = dataFromSever[item2.key];
                    });

PPS: Man kann das noch weiter vereinfachen, wenn man die Klassen gleich den Keys in den Daten vom Server setzt. Würde dann so aussehen:
Code:
    <div id="cont1">
        <div class="Total"></div>
        <div class="Voltage"></div>
    </div>

    <div id="cont2">
        <div class="Total"></div>
        <div class="Voltage"></div>
    </div>
    <script>
        const data = [
            {
                url: 'thread1245-fetch-javascript-forum-1.json',
                idCont: 'cont1'
            },
            {
                url: 'thread1245-fetch-javascript-forum-2.json',
                idCont: 'cont2'
            }
        ];
        data.forEach(item => {
            fetch(item.url).then(function (response) {
                // Aus der Antwort vom Server
                // das geparste JSON zurück geben:
                return response.json();
            }).then(function (parsed) {
                // Jetzt steht das geparste JSON zur Verfügung.
                const cont = document.getElementById(item.idCont);
                for (key in parsed.StatusSNS.ENERGY) {
                    const dest = cont.querySelector('.' + key);
                    if (dest) {
                        dest.innerHTML = parsed.StatusSNS.ENERGY[key];
                    }
                };
            });
        });
    </script>
Glaube denen, die die Wahrheit suchen, und zweifle an denen, die sie gefunden haben.
(Andrι Gide (1869-1951), frz. Schriftst., 1947 Nobelpreis)
Zitieren
#9
Guten Abend Ulrich,

vielen Lieben Dank, das passt! Dein PPS macht genau das was ich will, muss nur durchsteigen wie Du das in JS umgesetzt hast.
Das wird dauern, progge mir ESP32/8266 Devices in C++ und da bin ich auch noch Mittelmaß und für die ganze Geschichte sind es jetzt an die 5 Sprachen zu lernen... gleichzeitig Smile

Danke das Du mir dabei in JS hilfst!
Zitieren
#10
Hallo Ulrich,

Du bist mein Held! Habe es jetzt geschafft meine Seite zu JavaScriptusieren Big Grin .
Bin total Happy, läuft Perfekt!
Vielleicht kann ich Dir mal nen Kaffee ausgeben Wink

MAT
Zitieren


Gehe zu:


Benutzer, die gerade dieses Thema anschauen:
1 Gast/Gäste