Update Datensätze aus API Response
Hallo Forum,
ich brauche mal wieder Hilfe weil ich selbst mich verbissen habe und nicht weiter komme.
Folgendes Problem:
Ich habe eine Tabelle zu einem Wertpapiere X, einen Kurswert Y und ein Datum/Zeit enthält. Mit einem JSON API Aufruf frage ich nun für die Wertpapiere den aktuellen Kurswert aus einem Server ab. Zurück bekomme ich eine folgende Nachricht:
{"result":{"Wertpapier 1":{"usd":1.23},"Wertpapier 2":{"usd":234.12},"Wertpapier 3":{"usd":4.67}}}
Bis dahin alles OK. Doch bei dem Versuch, den String nach Wertpapier und Betrag aufzusplitten und jeweils mit dem aktuellen Datum/Uhrzeit in die oben genannte Tabelle einen Datensatz mit Wertpapier X, Kurswert Y, Datum/Zeit, anzuhängen, scheitere ich.
Könnt Ihr mir helfen?
Vielen Dank!
4 Antworten
-
Mir ist keine Möglichkeit bekannt, um mit Ninox eigenen Mitteln die JSON-Object Keys auszulesen.
Es besteht aber die Möglichkeit mit einem inoffiziellem Hack daran zu kommen.
Mit diesem Hack bekommt man die Möglichkeit JavaScript direkt in Ninox auszuführen.
Grundlage dafür ist ein Funktionsfeld, welches folgendes Script enthält:
Script von Jacques TUR
html(" <script> debugger; //get the address of the Eval function of NinoxScript var evalFunctor = queries.getFunctor('eval', [{ sign: function () { return 'string' } }, { sign: function () { return 'nid' } }]); //get the execution context of the NinoxScripts var Ctx = new queries.JSRuntimeContext(); //setting up the hook function if (evalFunctor && Ctx /* && !evalFunctor.oldFunction*/) { //save the old eval function, the one with the parameters eval(string,nid) if (evalFunctor.argTypes[0] == 'string') { evalFunctor.oldFunction = Ctx.F[evalFunctor.functorId]; } //initialization of new parameter types: eval(any,any) evalFunctor.argTypes[0] = 'any'; evalFunctor.argTypes[1] = 'any'; evalFunctor.sign = 'eval(any,any)'; //creation of the new extended function table evalFunctor.exFunctions = {}; //add extended functions to the array evalFunctor.exFunctions['exEvalJS'] = exEvalJS; evalFunctor.exFunctions['exComments'] = exComments; /* Implementation of the new function eval in the Ninox functions array. Now the eval function can be called in two ways. 1 - In the case of a call to the original eval function: fnt: Ninox code to be evaluated. params: Current record (this) which will be used as a context to evaluate the fnt code. 2 - In the case of a call to the extended functions: fnt: string that contains either the name of the extended function. params : object which contains the parameters of the extended functions call. in both cases : db : database object. ret : function to call at the end of the function. The functions are called by stacking. When the first one is finished, it calls the next one. */ evalFunctor.hook = function (fnt, params, db, ret) { try { //search if the first parameter of the eval function strictly contains the name of an extended function if (evalFunctor.exFunctions[fnt]) { //if this is the case, the corresponding function is called evalFunctor.exFunctions[fnt](fnt, params, db, ret); } else { //If not, the Ninox function is called evalFunctor.oldFunction(fnt, params, db, ret); } } catch (err) { //in case of an error, the error message is returned through the 'ret' return function ret(String(err.message)); } }; //recording the hooked function in the NinoxScript function array Ctx.F[evalFunctor.functorId] = evalFunctor.hook; } //returns the record id from its number or from the record object function getId(record) { if (typeof record === 'string') return record; else if (typeof record === 'object') return record._id; else return null; } /* extended function that allows the execution of JavaScript code eval('exEvalJS', {javascript:, arguments:{param1:, param2:...}}) javascript : string that contains the code to be executed arguments : { param1, param2… : parameters passed to the code as arguments to a function } return : result of JavaScript fonction. exemple :eval('exEvalJS', { javascript: 'return a + b;'', arguments : { a: 10, b: 20 } }); result -> 30; important: for an asynchronous function, call cb('return value') rather than return 'return value' exemple : promise.then( (value) => { cb(value); } ).then(); */ function exEvalJS(fnt, params, db, cb) { try { debugger; var { javascript, arguments } = params; var head = `var {${Object.keys(arguments).join(',')}} = args;`; var all = head + '\n' + javascript; var fn = Function('args', 'cb', all,); try { var Result = fn(arguments, cb); //check if function use CallBack to return result asynchronously if (javascript.search(/\b(cb)\b/) < 0) return cb(Result); } catch (err) { var msgErr = err.message + ' à la ligne ' + err.line - 2 + ', colonne ' + err.column; return cb(err) } } catch (err) { var msgErr = err.message + 'exEvalJS : à la ligne ' + err.line + ', colonne ' + err.column; cb(msgErr); } } /* getting the list of comments of a record eval('exComments', {id:} ) return array of JSON with : comment : string of comment, userId : id of user post the comment, date : date of post in milli seconde. exemple : eval('exComments', {id:this.id}); result -> {comment:... ,userId:..., date:167533002 } */ function exComments(fnt, params, db, cb) { database.loadComments(getId(params.id), function (error, commentsArray) { if (error) cb('exComments : ' + error); else { var commentsList = []; for (num in commentsArray) { var o = { comment: commentsArray[num][2], userId: commentsArray[num][1], date: new Date(commentsArray[num][0]), }; commentsList.push(o); } cb(commentsList); } }); } </script> ")
Dieses Funktionsfeld muss einmalig nach dem Start von Ninox aufgerufen werden.
Dann kann man mit folgender Funktion die Namen der im JSON enthaltenen Object-Keys auslesen:
Script in ein Funktionsfeld zum Testen kopieren.
eval("exEvalJS", { javascript: "return Object.keys(a);", arguments: { a: { result: { FreizeitAktie: { usd: 1.23 }, HochHinaus: { usd: 234.12 }, 'Glückauf': { usd: 4.67 } } }.result } })
Da mir auch kein Weg bekannt ist, wie man ein JSON-Object über Variablennamen auswerten kann habe ich das mal mit dem JavaScript-Hack weiter gebaut.
Anbei eine Beispieldatenbank, die dein Response in eine Tabelle schreibt.
Inwieweit, es bei neuen Ninox-Updates funktioniert, muss man testen.
Mit der neuen 3.7.0 läuft es jedenfalls.
-
Oh, je. Das ist aber eine Menge Code.
Ich würde zuerst aber damit versuchen:
let myRes := Response.result; let myText := formatJSON(myRes); let myLength := length(myText); myText := substr(myText, 1, myLength - 2); let myArray := split(myText, ","); let myNamesArray := for i in myArray do replace(first(split(text(i), ":")), """", "") end; for i in myNamesArray do let new := (create Wertpapiere); new.(Wertpapier := i); new.(Zeitpunkt := now()); new.(Kurswert := item(myRes, i).usd) end
Leo
-
Hallo Leo,
... immer wieder beeindruckend!!!
Nachdem ich nun x Zeilen Code geschrieben habe und es doch nur bis zum Update der Datensätze in der Tabelle reichte, kommst Du mit so ein paar lächerlichen Zeilen Code und es funktioniert auf Anhieb perfekt.
Ich ziehe abermals meinen Hut auf's Neue vor Dir !!!
Vielen Dank!
Und natürlich auch vielen Dank an Uwe - auch wenn es hier mit der Lösung von Leo schneller ist, kann man das Script von Dir vlt. doch an anderer Stelle brauchen...
Content aside
- vor 2 JahrenZuletzt aktiv
- 4Antworten
- 264Ansichten
-
3
Folge bereits