httpParamSerializerJQLike in angular2? - http

How to serialize JSON for Ruby API?
Angular 1
$scope.submitForm = function() {
var data = {"contato": $scope.contato, "id":$scope.contato.id, "_method":'PUT'};
$http.post(
'http://myApi/contatos/' + $scope.contato.id,
**$httpParamSerializerJQLike(data)**,
{
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
datatype: "JSONP"
}).then(function successCallback(response) {
modalContato.show();
setTimeout(function (){
modalContato.hide();
$state.go('contato-detalhe', {"id":$scope.contato.id});
}, 1500);
});
};
Angular2:
insertContato(contato: Contato) {
let headers = new Headers({
'Content-Type': 'application/x-www-form-urlencoded'
});
let options = new RequestOptions({ headers: headers });
this._http
.post(this.urlApi + '/contatos', JSON.stringify(contato), options)
.subscribe(data => {
console.log('Funciona: ' + data.text());
}, error => {
console.log('Erro: ' + error.text())
});
}
"JSON.stringify(contato)"
It does not have the same behavior as $httpParamSerializerJQLike(data).
Json's broken in the server...
Started POST "/contatos" for 127.0.0.1 at 2016-04-13 13:25:55 -0300
Processing by ContatosController#create as HTML
Parameters: {"{\"nome\":\"asd\",\"email\":\"asd#asda.com\",\"telefone\":\"123\"}"=>nil}
Completed 400 Bad Request in 4ms (ActiveRecord: 0.0ms)
Correct is:
Started POST "/contatos" for 127.0.0.1 at 2016-04-12 17:00:24 -0300
Processing by ContatosController#create as JSON
Parameters: {"contato"=>{"nome"=>"felipe", "telefone"=>"5555"}}
Completed 200 OK in 278ms (Views: 0.1ms | ActiveRecord: 229.4ms)

I had a similar problem, i can solve this:
import { Headers, Http, Response, URLSearchParams, RequestOptions } from '#angular/http';
let headers = new Headers({
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': '*/*'});
let options = new RequestOptions({ headers: headers });
let body = new URLSearchParams();
body.set("message", JSON.stringify(m_dataRequest));
body.set("webService", "authService");
return this.http
.post(this.Url, body.toString(), options)
.toPromise()
.then(this.extractData)
.catch(this.handleError);
URLSearchParams normalized the params of the form and the pipes dimiss, this work for me.
I hope this solve your problem.

I'm going to preface this by saying that this may not be the best way to handle this, but it's how I took care of the problem for myself (The Angular 2 docs don't seem to mention x-www-form-urlencoded anywhere).
So if your data is set up like
var data = {"contato": $scope.contato, "id":$scope.contato.id, "_method":'PUT'};
You want to basically convert it to a form yourself.
var encodedData = "contato=" + contato + "&id=" + contato.id + "&_method=PUT";
then you can modify your POST request to look like this
this._http
.post(this.urlApi + '/contatos', encodedData, options)
.subscribe(data => {
console.log('Funciona: ' + data.text());
}, error => {
console.log('Erro: ' + error.text())
});
There's no need to JSON.stringify it since you're not passing json, you're passing form data.
I hope this helps.

I wrote a function in my http.ts provider like so ---
private formatData(data){
let returnData = '';
console.log(data);
let count = 0;
for (let i in data){
if(count == 0){
returnData += i+'='+data[i];
}else{
returnData += '&'+i+'='+data[i];
}
count = count + 1;
console.log(returnData);
}
return returnData;
}
Call it like this.
post('localhost/url',data){
data = this.formatData(data);
}

Just copy the relative codes from angularjs http module
import {
isArray,
forEach,
isObject,
isDate,
isFunction,
isUndefined,
isNumber,
} from 'lodash';
function toJsonReplacer(key, value) {
let val = value;
if (
typeof key === 'string' &&
key.charAt(0) === '$' &&
key.charAt(1) === '$'
) {
val = undefined;
}
return val;
}
function toJson(obj, pretty = undefined) {
if (isUndefined(obj)) return undefined;
if (!isNumber(pretty)) {
pretty = pretty ? 2 : null; // tslint:disable-line no-parameter-reassignment
}
return JSON.stringify(obj, toJsonReplacer, pretty);
}
function serializeValue(v) {
if (isObject(v)) {
return isDate(v) ? v.toISOString() : toJson(v);
}
return v;
}
function forEachSorted(obj, iterator, context = null) {
const keys = Object.keys(obj).sort();
for (let i = 0; i < keys.length; i += 1) {
iterator.call(context, obj[keys[i]], keys[i]);
}
return keys;
}
/**
* This method is intended for encoding *key* or *value* parts of query component. We need a custom
* method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
* encoded per http://tools.ietf.org/html/rfc3986:
* query = *( pchar / "/" / "?" )
* pchar = unreserved / pct-encoded / sub-delims / ":" / "#"
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
* pct-encoded = "%" HEXDIG HEXDIG
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
* / "*" / "+" / "," / ";" / "="
*/
function encodeUriQuery(val, pctEncodeSpaces = undefined) {
return encodeURIComponent(val)
.replace(/%40/gi, '#')
.replace(/%3A/gi, ':')
.replace(/%24/g, '$')
.replace(/%2C/gi, ',')
.replace(/%3B/gi, ';')
.replace(/%20/g, pctEncodeSpaces ? '%20' : '+');
}
export function jQueryLikeParamSerializer(params) {
if (!params) return '';
const parts = [];
serialize(params, '', true);
return parts.join('&');
function serialize(toSerialize, prefix, topLevel = undefined) {
if (isArray(toSerialize)) {
forEach(toSerialize, (value, index) => {
serialize(value, prefix + '[' + (isObject(value) ? index : '') + ']');
});
} else if (isObject(toSerialize) && !isDate(toSerialize)) {
forEachSorted(toSerialize, (value, key) => {
serialize(
value,
prefix + (topLevel ? '' : '[') + key + (topLevel ? '' : ']'),
);
});
} else {
if (isFunction(toSerialize)) {
toSerialize = toSerialize(); // tslint:disable-line no-parameter-reassignment
}
parts.push(
encodeUriQuery(prefix) +
'=' +
(toSerialize == null
? ''
: encodeUriQuery(serializeValue(toSerialize))),
);
}
}
}

I've met the similar issue when was upgrading from angular 1.x
Here is my solution which also process nested JSON objects:
function Json2FormEncoded(json_obj) {
let path = arguments[1] || '';
let s = '', p = '';
for (let i in json_obj) {
p = path == '' ? i : path + '[' + i + ']';
s = s ? s + "&" : s;
if (typeof json_obj[i] == 'object') {
s += Json2FormEncoded(json_obj[i], p);
} else {
s += p + '=' + encodeURIComponent(json_obj[i]);
}
}
return s;
}
Hope you'll find it useful!
Also check it here

Related

Can't track events of Looker Embedded Dashborard (SSO embedded) in Nest.JS application

I have next.js project, on server side I generate Looker-sso url and on client side I use this url for embedded dashboard.
Here is how I generate SSO url at Next.js server side
function getLookerSsoUrl(embeddedUserParams: UserInfo, dashboardId: string) : string {
/** Returns Looker Embedded sso url. */
const url_data : LookerEmbeddedUrlOptions = {
"host": LOOKER_HOST,
"secret": LOOKER_SECRET,
"first_name": embeddedUserParams.firstName,
"last_name": embeddedUserParams.lastName,
"external_user_id": embeddedUserParams.firstName + " " + embeddedUserParams.lastName,
"external_group_id": embeddedUserParams.companyName + " group",
"group_ids": [1],
"access_filters": {},
"models": ['db_analytics'],
"permissions": [
'see_user_dashboards',
'see_lookml_dashboards',
'access_data',
'see_looks'],
"user_attributes": {
"name": embeddedUserParams.firstName + " " + embeddedUserParams.lastName,
"first_name": embeddedUserParams.firstName,
"last_name": embeddedUserParams.lastName,
"email": embeddedUserParams.email,
"company_id": embeddedUserParams.companyId,
"company_name": embeddedUserParams.companyName,
"id": embeddedUserParams.id
},
"session_length": 15 * 60,
"embed_url": `/embed/dashboards/${dashboardId}?embed_domain=http://localhost&company_id=${embeddedUserParams.companyId}`,
"force_logout_login": true
}
return "https://" + getSignedEmbedUrl(url_data)
}
function getSignedEmbedUrl(options : LookerEmbeddedUrlOptions) : string {
/** Build sso url with all Looker options and secret key and returns it. */
// looker options
const secret = options.secret
const host = options.host
// user options
const json_external_user_id = JSON.stringify(options.external_user_id)
const json_first_name = JSON.stringify(options.first_name)
const json_last_name = JSON.stringify(options.last_name)
const json_permissions = JSON.stringify(options.permissions)
const json_models = JSON.stringify(options.models)
const json_group_ids = JSON.stringify(options.group_ids)
const json_external_group_id = JSON.stringify(options.external_group_id || "")
const json_user_attributes = JSON.stringify(options.user_attributes || {})
const json_access_filters = JSON.stringify(options.access_filters)
// url/session specific options
const embed_path = '/login/embed/' + encodeURIComponent(options.embed_url)
const json_session_length = JSON.stringify(options.session_length)
const json_force_logout_login = JSON.stringify(options.force_logout_login)
// computed options
const json_time = JSON.stringify(Math.floor((new Date()).getTime() / 1000))
const json_nonce = JSON.stringify(getNonce(16))
// compute signature
let string_to_sign = ""
string_to_sign += host + "\n"
string_to_sign += embed_path + "\n"
string_to_sign += json_nonce + "\n"
string_to_sign += json_time + "\n"
string_to_sign += json_session_length + "\n"
string_to_sign += json_external_user_id + "\n"
string_to_sign += json_permissions + "\n"
string_to_sign += json_models + "\n"
string_to_sign += json_group_ids + "\n"
string_to_sign += json_external_group_id + "\n"
string_to_sign += json_user_attributes + "\n"
string_to_sign += json_access_filters
const signature = createHmac('sha1', secret).update(ForceUnicodeEncoding(string_to_sign)).digest('base64').trim()
// construct query string
const query_params = {
nonce: json_nonce,
time: json_time,
session_length: json_session_length,
external_user_id: json_external_user_id,
permissions: json_permissions,
models: json_models,
access_filters: json_access_filters,
first_name: json_first_name,
last_name: json_last_name,
group_ids: json_group_ids,
external_group_id: json_external_group_id,
user_attributes: json_user_attributes,
force_logout_login: json_force_logout_login,
signature: signature
}
const query_string = stringify(query_params)
return host + embed_path + '?' + query_string
}
function getNonce(len : number) : string {
/** Returns nonce characters. */
let text = ""
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
for (let i = 0; i < len; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length))
return text
}
function ForceUnicodeEncoding(string : string) : string {
/** Decodes a URI component previously created by encodeURIComponent. */
return decodeURIComponent(encodeURIComponent(string))
}
Here is client side code:
import React, {useCallback} from "react"
import {LookerEmbedSDK} from "#looker/embed-sdk"
import {ENV_VAR} from "env"
type embeddedDashboardType = {
id : number
setError? : ((errorMsg : string) => void)
}
export const EmbeddedDashboard = ({id, setError} : embeddedDashboardType) => {
const canceller = (event : any) => {
return { cancel: !event.modal }
}
document.addEventListener("click", ()=>console.log("r"))
const embedCtrRef = useCallback((el) => {
const authUrl = "/api/looker-sso"
if (el) {
LookerEmbedSDK.init("...", authUrl)
LookerEmbedSDK.createDashboardWithId(id)
.withNext()
.appendTo(el)
.on("drillmenu:click", canceller)
.on("drillmodal:explore", canceller)
.on("dashboard:tile:explore", canceller)
.on("look:ready", ()=> console.log("ready"))
.on("explore:ready", ()=>console.log("ready"))
.on("dashboard:run:start", ()=>console.log("ready"))
.on("dashboard:tile:view", canceller)
.build()
.connect()
.catch((error) => {
console.error("Connection error", error)
if (setError){
setError(error)
}
})
}
}, [])
return <>
<style jsx>{`
:global(.container-dashboard) {
width: 100%;
height: 95vh;
}
:global(.container-dashboard > iframe) {
width: 100%;
height: 100%;
}
`}</style>
<div className="container-dashboard" ref={embedCtrRef} />
</>
}
The dashboard displays correctly, but I cant track events, that happen in Looker Iframe
I except, that I would see clicks, which are made on looker iframe

Force synchronous looping of http requests

I've been struggling with this piece of code for a while and I'm reaching out for help. I have a array of dates and I"m trying to make http requests in order of the array and to write the return information, also in order.
Here is my code:
const dateArray = ['november-22-2019', 'november-25-2019', 'november-26-2019', 'november-27-2019', 'november-29-2019'];
async function loppThroughArray() {
for (const date of dateArray) {
const options = {
url: process.env.URL + date
};
await asyncRequest(options, date);
}
}
async function asyncRequest(options, date) {
request(options, function(error, response, html) {
if (error) {
return;
}
if (response.statusCode !== 200) {
return;
}
const $ = cheerio.load(html);
const content = $('.entry-content');
const formattedContent = content.text()
.split('\t').join('')
.split('\n\n\n').join('')
.split('\n\n').join('');
const dataToBeWritten = '### ' + date + '\n' + formattedContent + '\n\n';
fs.appendFileSync(`./WODs/${currentDate}.md`, dataToBeWritten, 'utf-8', {'flags':'a+'});
fs.appendFileSync(`./WODs/${currentDate}.txt`, dataToBeWritten, 'utf-8', {'flags':'a+'});
});
}
loppThroughArray();
I managed to solve this by using a version of 'request' that uses promises instead of callbacks. See code:
async function loppThroughArray() {
for (const date of dateArray) {
const options = {
url: process.env.URL + date
};
await asyncRequest(options, date);
console.log('fetching: ', date);
}
}
async function asyncRequest(options, date) {
await rp(options)
.then(function(html){
const $ = cheerio.load(html);
const content = $('.entry-content');
const formattedContent = content.text()
.split('\t').join('')
.split('\n\n\n').join('')
.split('\n\n').join('');
const dataToBeWritten = '### ' + date + '\n' + formattedContent + '\n\n';
fs.appendFileSync(`./WODs/${currentDate}.md`, dataToBeWritten, 'utf-8', {'flags':'a+'});
fs.appendFileSync(`./WODs/${currentDate}.txt`, dataToBeWritten, 'utf-8', {'flags':'a+'});
});
}
loppThroughArray();

How To Modifying The Filename Before Uploading When Using Meteor Edgee:SlingShot Package

Please i am trying to modify the filename of a selected file posted by a user before uploading to Amazon S3 using the edgee:slinghot package. I can upload the file quite alright but the problem is how do i modify the filename.
I modified it on the client using by saving the modified name into a variable. My problem now is how to access that variable declared and saved on the Client in the Server environment. I just can't seem to wrap my head around it.
'change .js-submitTeamPaper' : function(event , template){
event.preventDefault();
let paper = template.paperDetails.get();
newFilename = paper[0].paper_name + "_"
_.map(paper[0].member , (member)=>{
newFilename += "_" + member.regnum + "_"
});
newFilename += paper[0]._id;
let file = event.target.value;
let fileArray = file.split(".");
let ext = fileArray[fileArray.length - 1];
newFilename += "." + ext;
studentFileUpload(event , template , 'submitTeamTermPaper' , 'divProgress');
}
The code to upload the file.
let _collectfile = (event , template) =>{
let file = event.target.files[0]
return file
}
let _showProgressBar = (div) => {
let _div = document.getElementById(div);
_div.classList.remove("hide");
}
let _closeProgressBar = (div) => {
let _div = document.getElementById(div);
_div.classList.add("hide");
}
let _slingShotUploadConfigure = (event , template , folder ,div) => {
let _upload = new Slingshot.Upload(folder);
let _file = _collectfile(event , template);
_showProgressBar(div);
_upload.send(_file , (error , downloadUrl) => {
template.uploader.set();
if (error){
//throw new Meteor.Error('500' , error.reason);
event.target.value = '';
sAlert.error(error.reason , {effect: 'bouncyflip',
position: 'bottom-right', timeout: 3000, onRouteClose: false, stack: false, offset: '150px'});
_closeProgressBar(div);
}
else{
sAlert.success('File was uploaded successfully' , {effect: 'genie',
position: 'bottom-right', timeout: 3000, onRouteClose: false, stack: false, offset: '150px'});
event.target.value = '';
template.downloadUrl.set(downloadUrl);
_closeProgressBar(div);
//return downloadUrl;
}
});
template.uploader.set(_upload);
}
export default function(event , template , folder ,div , progress){
return _slingShotUploadConfigure(event , template , folder,div , progress)
}
I then imported the module as studentFileUpload from '../../modules/handle-fileuploads';
Below is the meteor-slingshot code to do the upload
Slingshot.createDirective("submitTeamTermPaper", Slingshot.S3Storage, {
bucket: Meteor.settings.BucketName,
AWSAccessKeyId : Meteor.settings.AWSAccessKeyId,
AWSSecretAccessKey : Meteor.settings.AWSSecretAccessKey,
acl: "public-read",
authorize: function () {
// do some validation
// e.g. deny uploads if user is not logged in.
if (this.userId) {
return true;
}
},
key: function (file) {
//file here is the file to be uploaded how do i get the modified file name i defined in the client as newFilename here
let timeStamp = + new Date;
//let newFilename = file.name.replace(/_/g , "-");
return 'Team_Term_Papers/' + timeStamp + '_' + '_' + newFilename;
}
});
From my code newFilename is the variable that holds the modified filename. How do i access it from the server environment. Any help is really appreciated. Thanks
You can pass extra information through to slingshot using metacontext:
metacontext = {newName: "foo"};
let _upload = new Slingshot.Upload(folder,metacontext);
Then you can access that metacontext in your key function:
key: function (file,metacontext) {
let timeStamp = + new Date;
let newFilename = metacontext ? metacontext.newName : file.name;
newFilename = newFilename.replace(/_/g , "-");
return 'Team_Term_Papers/' + timeStamp + '_' + '_' + newFilename;
}

Apache Cordova using SQLite - Can't wait to return data

function outDb(outData) {
var temp;
var db = window.sqlitePlugin.openDatabase({ name: "test" });
db.executeSql("SELECT " + outData + " FROM test", [], function (res) {
switch (outData) {
case "goal": temp = res.rows.item(0).GOAL;
break;
case "curDate": temp = res.rows.item(0).CURDATE;
break;
case "Day1": temp = res.rows.item(0).DAY1;
break;
case "Day2": temp = res.rows.item(0).DAY2;
break;
case "Day3": temp = res.rows.item(0).DAY3;
break;
default: temp = "is default";
}
});
return temp;
}
I want to save data into myData;
var myData = outDb("goal");
But this is not working, because the return statement happens faster than the data is assigned to my variable.
What can I do?
You should use callback function because Cordova-sqlite-storage works asynchronously.
function getFromDB(_n, fn) {
var db = ...
db.transaction(function(tx) {
var query = "SELECT * FROM <table_name> WHERE <field_name> = ?";
tx.executeSql(query, [_n], function (tx, rs) {
for(var x = 0; x < rs.rows.length; x++) {
_res = rs.rows.item(x).value;
fn(_res);
}
}, function (tx, error) {
console.log('select error: ' + error.message);
});
}, function (error) {
console.log('transaction error: ' + error.message);
}, function () {
console.log('transaction ok.');
});}
getFromDB(<name>, function(val) {
console.log(val);});
All sqlite commands are event driven. That means, that you have to wait for values until the event is finished.
In your case: You will never get a return value, because your return is outside of the success function.
You could do a rewrite of your function like:
function outDb(outData) {
var temp;
var db = window.sqlitePlugin.openDatabase({ name: "test" });
db.executeSql("SELECT " + outData + " FROM test", [], function (res) {
switch (outData) {
case "goal": temp = res.rows.item(0).GOAL;
break;
case "curDate": temp = res.rows.item(0).CURDATE;
break;
case "Day1": temp = res.rows.item(0).DAY1;
break;
case "Day2": temp = res.rows.item(0).DAY2;
break;
case "Day3": temp = res.rows.item(0).DAY3;
break;
default: temp = "is default";
}
return temp;
});
}
A much better way is like I showed in this answer:
How to compact SQL instructions in Cordova?

Real time data and retrieval plotting

So my question is as follows: I'm working on a mobile application that takes data from a vital sign sensor and sends to a telehealth server, so that a physician is able to retrieve the data from the server in real time as a plotted curve.
As I have a very weak background on this, my question is of two parts: a) how do I retrieve the data from the server in real time and b) can I use HTML5 libs or anything similar like HighCharts or Meteor charts or ZingCharts to have them plotted or is it impossible? Please be very specific as again I have a weak background on this :)
In ZingChart, you can do this in two ways:
Method 1 - Via Websockets - EX: http://www.zingchart.com/dataweek/presentation/feed.html
The websocket transport is part of the refresh/feed section, its attribute can be found here: Graph >> Refresh section of the ZingChart JSON docs. In addition, a server socket component is required and it has to follow some standard protocol in order to allow connectivity and transport with the client socket.
To get specific:
###############################
# NodeJS code
###############################
#!/usr/bin/env node
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {
response.writeHead(404);
response.end();
});
server.listen(8888, function() {
console.log((new Date()) + ' Server is listening on port 8888');
});
wsServer = new WebSocketServer({
httpServer: server,
autoAcceptConnections: false
});
function originIsAllowed(origin) {
return true;
}
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
var type = '',
method = '',
status = 0;
var connection = request.accept('zingchart', request.origin);
connection.on('message', function(message) {
function startFeed() {
console.log('start feed');
status = 1;
if (method == 'push') {
sendFeedData();
}
}
function stopFeed() {
console.log('stop feed');
status = 0;
}
function sendFeedData() {
if (method == 'push') {
var ts = (new Date()).getTime();
var data = {
"scale-x": ts,
"plot0": [ts, parseInt(10 + 100 * Math.random(), 10)]
};
console.log('sending feed data (push)');
connection.sendUTF(JSON.stringify(data));
if (status == 1) {
iFeedTick = setTimeout(sendFeedData, 500);
}
} else if (method == 'pull') {
var data = [];
var ts = (new Date()).getTime();
for (var i = -5; i <= 0; i++) {
data.push({
"scale-x": ts + i * 500,
"plot0": [ts + i * 500, parseInt(10 + 100 * Math.random(), 10)]
});
}
console.log('sending feed data (pull)');
connection.sendUTF(JSON.stringify(data));
}
}
function sendFullData() {
var data = {
type: "bar",
series: [{
values: [
[(new Date()).getTime(), parseInt(10 + 100 * Math.random(), 10)]
]
}]
};
console.log('sending full data');
connection.sendUTF(JSON.stringify(data));
if (status == 1) {
if (method == 'push') {
setTimeout(sendFullData, 2000);
}
}
}
if (message.type === 'utf8') {
console.log('************************ ' + message.utf8Data);
switch (message.utf8Data) {
case 'zingchart.full':
type = 'full';
break;
case 'zingchart.feed':
type = 'feed';
break;
case 'zingchart.push':
method = 'push';
break;
case 'zingchart.pull':
method = 'pull';
break;
case 'zingchart.startfeed':
startFeed();
break;
case 'zingchart.stopfeed':
stopFeed();
break;
case 'zingchart.getdata':
status = 1;
if (type == 'full') {
sendFullData();
} else if (type == 'feed') {
sendFeedData();
}
break;
}
}
});
connection.on('close', function(reasonCode, description) {
status = 0;
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
###############################################
# Sample JSON settings for socket transport
###############################################
refresh: {
type: "feed",
transport: "websockets",
url: "ws://198.101.197.138:8888/",
method: "push",
maxTicks: 120,
resetTimeout: 2400
}
or
refresh: {
type: "feed",
transport: "websockets",
url: "ws://198.101.197.138:8888/",
method: "pull",
interval: 3000,
maxTicks: 120,
resetTimeout: 2400
}
Method 2 - Via API - EX: http://www.zingchart.com/dataweek/presentation/api.html
In the case you described, this would involve setting intervals of time at which you would like to retrieve data from your server, and then pass that data via the API. Check out the "Feed" section in API-Methods section of the ZingChart docs.

Resources