Skip to content

Instantly share code, notes, and snippets.

@kenwebb

kenwebb/xholonWorkbook.xml

Last active May 22, 2020
Embed
What would you like to do?
Ramda-based Web Client
<?xml version="1.0" encoding="UTF-8"?>
<!--Xholon Workbook http://www.primordion.com/Xholon/gwt/ MIT License, Copyright (C) Ken Webb, Fri May 22 2020 09:48:16 GMT-0400 (Eastern Daylight Time)-->
<XholonWorkbook>
<Notes><![CDATA[
Xholon
------
Title: Ramda-based Web Client
Description:
Url: http://www.primordion.com/Xholon/gwt/
InternalName: 9eb896384969b169d43bfdea79743cb3
Keywords:
My Notes
--------
May 16, 2020
127.0.0.1:8888/Xholon.html?app=Ramda-based Web Client&src=lstr&gui=clsc&jslib=ramda.min
TODO
- handle CORS error
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://api.flickr.com/services/feeds/photos_public.gne?tags=cats&format=json&jsoncallback=?.
Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
TypeError: NetworkError when attempting to fetch resource.
May 21, 2020
------------
nodejs/npm http-server
----------------------
$ npm install --global http-server
$ cd ~/gwtspace/Xholon/Xholon
$ http-server
Starting up http-server, serving ./
Available on:
http://127.0.0.1:8080
http://192.168.0.39:8080
Hit CTRL-C to stop the server
# in the browser (Firefox)
http://127.0.0.1:8080/war/Xholon.html?app=9eb896384969b169d43bfdea79743cb3&src=gist&gui=clsc&jslib=ramda.min
http://127.0.0.1:8080/war/Xholon.html?app=Ramda-based+Web+Client&src=lstr&gui=clsc&jslib=ramda.min
http://127.0.0.1:8080/war/Xholon.html?app=Ramda-based+Web+Client&src=lstr&gui=clsc&jslib=ramda.min,jquery-3.5.1.min
http://127.0.0.1:8080/war/Xholon.html?app=Ramda-based+Web+Client&src=lstr&gui=clsc&jslib=ramda.min,jquery-3.5.1.min,fetch-jsonp
http://127.0.0.1:8080/war/Xholon.html?app=Ramda-based+Web+Client&src=lstr&gui=clsc&jslib=ramda.min,fetch-jsonp
fetch-jsonp
-----------
fetchJsonp('https://api.flickr.com/services/feeds/photos_public.gne?tags=cats&format=json')
.then(function(response) {
return response.json()
}).then(function(json) {
console.log('parsed json', json)
}).catch(function(ex) {
console.log('parsing failed', ex)
})
fetch-jsonp example
-------------------
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Fetch JSONP example</title>
<script src="../build/fetch-jsonp.js"></script>
</head>
<body>
<script>
var result = fetchJsonp('http://www.flickr.com/services/feeds/photos_public.gne?format=json', {
jsonpCallback: 'jsoncallback',
timeout: 3000
})
result.then(function(response) {
return response.json()
}).then(function(json) {
document.body.innerHTML = JSON.stringify(json);
})['catch'](function(ex) {
document.body.innerHTML = 'failed:' + ex;
})
</script>
</body>
</html>
https://api.flickr.com/services/feeds/photos_public.gne?tags=cats&format=json&jsoncallback=jQuery35105491595841710111_1590094833738&_=1590094833739
References
----------
(1) https://gist.github.com/kenwebb/c0da906c2412e2e7aab073a4476033a8
Mostly Adequate
Mostly Adequate exercises/ch06
(2) https://github.com/MostlyAdequate/mostly-adequate-guide
(3) https://mostly-adequate.gitbooks.io/mostly-adequate-guide/
(4) https://github.com/camsong/fetch-jsonp
Make JSONP request like window.fetch
JSONP is NOT supported in standard Fetch API, https://fetch.spec.whatwg.org.
fetch-jsonp provides you same API to fetch JSONP like native Fetch, also comes with global fetchJsonp function.
JSONP only supports GET method, same as fetch-jsonp.
]]></Notes>
<_-.XholonClass>
<PhysicalSystem/>
<WebClientA/>
<WebClientB/>
<WebClientC/>
</_-.XholonClass>
<xholonClassDetails>
</xholonClassDetails>
<PhysicalSystem>
<WebClientA/>
<WebClientB/>
<WebClientC/>
</PhysicalSystem>
<WebClientAbehavior implName="org.primordion.xholon.base.Behavior_gwtjs"><![CDATA[
// ========================================= Fetch API version - not working - fetch doesn't support a jsonp approach; use fetch-jsonp instead
const enabled = false;
const doMostlyAdeqt = function(me, R) {
// -- Utils ----------------------------------------------------------
const Impure = {
trace: R.curry((tag, x) => { console.log(tag, x); return x; }), // eslint-disable-line no-console
getJSON: R.curry((callback, url) => fetch(url, {mode: 'no-cors'}) // 'cors' by default
.then(response => response.json())
.then(data => Impure.trace("json ", data))),
setHtml: R.curry((sel, html) => $doc.querySelector(sel).appendChild(html))
};
// -- Pure -----------------------------------------------------------
const host = 'api.flickr.com';
const path = '/services/feeds/photos_public.gne';
const query = t => `?tags=${t}\u0026format=json\u0026jsoncallback=callback`;
const url = t => `https://${host}${path}${query(t)}`;
const img = src => {
var ele = document.createElement("IMG");
ele.setAttribute("src", `${src}`); // `
return ele;
}
const mediaUrl = R.compose(R.prop('m'), R.prop('media'));
const mediaUrls = R.compose(R.map(mediaUrl), R.prop('items'));
const images = R.compose(R.map(img), mediaUrls);
// -- Impure ---------------------------------------------------------
const render = R.compose(Impure.setHtml('#xhappspecific'), images);
const app = R.compose(Impure.getJSON(render), url);
app('cats');
}
// =========================================
var me, R, beh = {
postConfigure: function() {
if (enabled) {
me = this.cnode.parent();
R = $wnd.R;
} else {
this.cnode.remove();
}
},
act: function() {
me.println(R);
me.println(R.add(2,3));
doMostlyAdeqt(me, R);
}
}
//# sourceURL=WebClientAbehavior.js
]]></WebClientAbehavior>
<WebClientBbehavior implName="org.primordion.xholon.base.Behavior_gwtjs"><![CDATA[
// ========================================= jquery version - this works - this is the original Mostly Adequate example
const enabled = false;
const doMostlyAdeqt = function(me, R) {
// -- Utils ----------------------------------------------------------
const Impure = {
trace: R.curry((tag, x) => { console.log(tag, x); return x; }), // eslint-disable-line no-console
getJSON: R.curry((callback, url) => $wnd.$.getJSON(url, callback)),
setHtml: R.curry((sel, html) => $wnd.$(sel).html(html))
};
// -- Pure -----------------------------------------------------------
const host = 'api.flickr.com';
const path = '/services/feeds/photos_public.gne';
const query = t => `?tags=${t}\u0026format=json\u0026jsoncallback=?`;
const url = t => `https://${host}${path}${query(t)}`;
const img = src => $wnd.$('<img />', { src });
const mediaUrl = R.compose(R.prop('m'), R.prop('media'));
const mediaUrls = R.compose(R.map(mediaUrl), R.prop('items'));
const images = R.compose(R.map(img), mediaUrls);
// -- Impure ---------------------------------------------------------
const render = R.compose(Impure.setHtml('#xhappspecific'), images);
const app = R.compose(Impure.getJSON(render), url);
app('rocks'); // cats
}
// =========================================
var me, R, beh = {
postConfigure: function() {
if (enabled) {
me = this.cnode.parent();
R = $wnd.R;
} else {
this.cnode.remove();
}
},
act: function() {
doMostlyAdeqt(me, R);
}
}
//# sourceURL=WebClientBbehavior.js
]]></WebClientBbehavior>
<WebClientCbehavior implName="org.primordion.xholon.base.Behavior_gwtjs"><![CDATA[
// ========================================= fetch-jsonp version - this works
const enabled = true;
const doMostlyAdeqt = function(me, R) {
// -- Utils ----------------------------------------------------------
const Impure = {
trace: R.curry((tag, x) => { console.log(tag, x); return x; }), // eslint-disable-line no-console
// 1. You need to call .then(function(response) { return response.json(); }) in order to keep consistent with Fetch API. [ref 4]
// 2. Uncaught SyntaxError: Unexpected token : error More than likely, you are calling a JSON api, which does not support JSONP. [ref 4]
getJSON: R.curry((callback, url) => $wnd.fetchJsonp(url, {
jsonpCallback: 'jsoncallback',
timeout: 3000
})
.then(function(response) {
return response.json();
}).then(function(json) {
Impure.trace('parsed json', json);
callback(json);
}).catch(function(ex) {
console.log('parsing failed', ex);
})),
setHtml: R.curry((sel, htmlarr) => {
let ele = $doc.querySelector(sel);
htmlarr.forEach(element => ele.appendChild(element));
})
};
// -- Pure -----------------------------------------------------------
const host = 'api.flickr.com';
const path = '/services/feeds/photos_public.gne';
const query = t => `?tags=${t}\u0026format=json`;
const url = t => `https://${host}${path}${query(t)}`;
const img = src => {
let ele = $doc.createElement("IMG"); // document vs $doc; they both work here
ele.setAttribute("src", `${src}`); // `
return ele;
}
const mediaUrl = R.compose(R.prop('m'), R.prop('media'));
const mediaUrls = R.compose(R.map(mediaUrl), R.prop('items'), Impure.trace('mediaUrls'));
const images = R.compose(R.map(img), mediaUrls);
// -- Impure ---------------------------------------------------------
const render = R.compose(Impure.setHtml('#xhappspecific'), Impure.trace('images'), images);
const app = R.compose(Impure.getJSON(render), Impure.trace('url'), url);
app('circle');
}
// =========================================
var me, R, doAct, beh = {
postConfigure: function() {
if (enabled) {
me = this.cnode.parent();
R = $wnd.R;
doAct = true;
} else {
this.cnode.remove();
}
},
act: function() {
if (doAct) {
doMostlyAdeqt(me, R);
doAct = false; // only do act() functionality once
}
}
}
//# sourceURL=WebClientCbehavior.js
]]></WebClientCbehavior>
<SvgClient><Attribute_String roleName="svgUri"><![CDATA[data:image/svg+xml,
<svg width="100" height="50" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Block</title>
<rect id="PhysicalSystem/WebClientC" fill="#98FB98" height="50" width="50" x="25" y="0"/>
<g>
<title>Height</title>
<rect id="PhysicalSystem/WebClientC/*" fill="#6AB06A" height="50" width="10" x="80" y="0"/>
</g>
</g>
</svg>
]]></Attribute_String><Attribute_String roleName="setup">${MODELNAME_DEFAULT},${SVGURI_DEFAULT}</Attribute_String></SvgClient>
</XholonWorkbook>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.