Read the statement by Michael Teeuw here.
Display values from a JSON file hosted online
-
Want to display two fields from this file:
https://www.dropbox.com/s/k1t6mjjc3knxp3a/dataset.json?raw=1
Kind of like this:
Customers today - Astronomy department:
88The file looks like this:
{ "graph": { "title" : "Customers today", "total" : true, "datasequences" : [ { "title" : "Astronomy department", "datapoints" : [ { "title" : "Amount", "value" : 88 } ] } ] } }
I want to display the amount value (88 in the example), and the titles, (Customers today and Astronomy department in the example).
The module I have so far looks like this:
Module.register("MMM-backlog",{ // Default module config. defaults: { text: "test text" }, // Override dom generator. getDom: function() { var wrapper = document.createElement("div"); wrapper.innerHTML = this.config.text; return wrapper; } });
Anybody able to help me get it working?
-
Quick and dirty, but should get you going :)
You have to use the node_helper, because using XMLHttpRequest would result in an “origin error”.
MMM-backlog.js
/* global Module */ /* Magic Mirror * Module: MMM-backlog * * By Stefan Krause http://yawns.de * MIT Licensed. */ Module.register('MMM-backlog',{ defaults: { units: config.units, animationSpeed: 1000, updateInterval: 1000 * 3600, //update every hour refreshInterval: 1000 * 60 * 10, //refresh every minute timeFormat: config.timeFormat, lang: config.language, initialLoadDelay: 0, // 0 seconds delay retryDelay: 2500, fileUrl: "https://www.dropbox.com/s/k1t6mjjc3knxp3a/dataset.json?raw=1" }, // Define required scripts. getScripts: function() { return ["moment.js"]; }, // Define requird styles getStyles: function() { return ["font-awesome.css"]; }, start: function() { Log.info('Starting module: ' + this.name); this.loaded = false; this.sendSocketNotification('CONFIG', this.config); }, getDom: function() { var wrapper = document.createElement("div"); if (!this.loaded) { wrapper.innerHTML = this.translate('LOADING'); wrapper.className = "dimmed light small"; return wrapper; } if (!this.data) { wrapper.innerHTML = "No data"; wrapper.className = "dimmed light small"; return wrapper; } var t = this.data.graph; var content = document.createElement("div"); content.innerHTML = ""; for (var i in t.datasequences) { content.innerHTML += t.title + " - " + t.datasequences[i].title + "<br />"; for (var j in t.datasequences[i].datapoints) { content.innerHTML += t.datasequences[i].datapoints[j].title + ": " + t.datasequences[i].datapoints[j].value + "<br />"; } } wrapper.appendChild(content); return wrapper; }, socketNotificationReceived: function(notification, payload) { if (notification === "STARTED") { this.updateDom(); } else if (notification === "DATA") { this.loaded = true; this.processData(JSON.parse(payload)); this.updateDom(); } }, /* processData(data) * Uses the received data to set the various values. * * argument data object - tide information received form worldtides.info */ processData: function(data) { if (!data) { // Did not receive usable new data. // Maybe this needs a better check? return; } this.data = data; this.loaded = true; this.updateDom(this.config.animationSpeed); } });
node_helper.js
'use strict'; /* Magic Mirror * Module: MMM-backlog * * By Stefan Krause http://yawns.de * MIT Licensed. */ const NodeHelper = require('node_helper'); var request = require('request'); module.exports = NodeHelper.create({ start: function() { this.started = false; this.config = null; }, getData: function() { var self = this; var myUrl = this.config.fileUrl; request({ url: myUrl, method: 'GET', }, function (error, response, body) { if (!error && response.statusCode == 200) { self.sendSocketNotification("DATA", body); } }); setTimeout(function() { self.getData(); }, this.config.refreshInterval); }, socketNotificationReceived: function(notification, payload) { var self = this; if (notification === 'CONFIG' && self.started == false) { self.config = payload; self.sendSocketNotification("STARTED", true); self.getData(); self.started = true; } } });
-
wow! This looks great! I cant wait to try this out!
Thank you so much! 👍🏻
-
@yawns HAVE MY BABIES!
It works! Thank you so much! I’ll now start to play around with the CSS! Thank you so much! :)
-
Glad it gets you going. Of course you can add more divs/spans or even a table to place your output and adjust proper css to single lines or values.
If you need explanation of single commands or routines just let us know.@looolz said in Display values from a JSON file hosted online:
@yawns HAVE MY BABIES!
I doubt my wife would be happy with that :rofl:
-
You are very kind!
I’ve got a couple of issues so far:
1: The module doesn’t seem to survive a manual refresh. For some reason, if I hit CTRL R to refresh, all other modules load, but this one is stuck at “loading…” If I do CTRL Q, quit the Magic Mirror and try again, it works. Even more strangely, it does correctly update on it’s own, when the JSON file changes. Just a minor thing.
2: I’ve been trying to create en separate class for the value, so that I can style the number individually. So I tried to create an element that I can style with xlarge from the css file. But so far I’ve only been able to style the titles. I tried to read up on this on w3schools.com, but it’s evident that I lack a pillar of information to understand the syntax completely.
How would change the code to make the numbervalue an element I can style in the CSS?
-
1: This is a know issue. If the module uses a node_helper, it does not survive a manual refresh of the webpage. It requires a restart of the magic mirror process. If someone knows how to get rid of this, I am more than happy to learn. @Module-Developers
2:
getDom: function() { var wrapper = document.createElement("div"); if (!this.loaded) { wrapper.innerHTML = this.translate('LOADING'); wrapper.className = "dimmed light small"; return wrapper; } if (!this.data) { wrapper.innerHTML = "No data"; wrapper.className = "dimmed light small"; return wrapper; } var t = this.data.graph; var content = document.createElement("div"); var titleDiv = document.createElement("div"); var dataDiv = document.createElement("div"); var titleDataSpan = document.createElement("span"); var valueDataSpan = document.createElement("span"); for (var i in t.datasequences) { titleDiv.className = "LIST YOUR CLASSES HERE"; titleDiv.innerHTML = t.title + " - " + t.datasequences[i].title; content.appendChild(titleDiv); for (var j in t.datasequences[i].datapoints) { dataDiv.className = "LIST YOUR CLASSES HERE"; titleDataSpan.className = "LIST YOUR CLASSES HERE"; titleDataSpan.innerHTML = t.datasequences[i].datapoints[j].title + ":"; valueDataSpan.className = "LIST YOUR CLASSES HERE"; valueDataSpan.innerHTML = t.datasequences[i].datapoints[j].value; dataDiv.appendChild(titleDataSpan); dataDiv.appendChild(valueDataSpan); content.appendChild(dataDiv); } } wrapper.appendChild(content); return wrapper; },
You could even use the datapoint title (“amount” in this example), define a css class with this selector and add the datapoint title to the list of classnames ;)
I did not test it, I just wrote it in notepad++, so there might be a typo. You could also try to add more entries to your JSON file to see if the loops are correct and fetch all data. -
@yawns i could imagine that the start flag of the node_helper is still true so the getdata call gets skipped
-
@strawberry-3.141
good point. Maybe I find some time at the weekend to debug this and check where it is stopping/skipping -
@yawns Was that re-load issue ever resolved? I have my own basic issues and I’m considering using this code instead…