Skip to content

Commit

Permalink
Add JSON requests
Browse files Browse the repository at this point in the history
  • Loading branch information
nyanja authored and piranha committed Aug 21, 2024
1 parent fc68fb3 commit 90b2e78
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 7 deletions.
25 changes: 18 additions & 7 deletions twinspark.js
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@

/**
* Merge two sets of parameters into one
* @param {FormData|URLSearchParams} p1 Collection of parameters to be updated.
* @param {FormData} p1 Collection of parameters to be updated.
* @param {FormData|URLSearchParams|Iterable} p2 Collection of parameters to be merged in.
* @param {boolean=} removeEmpty Indicate if empty ('' or null) parameters from p2 should be removed.
* @return FormData|URLSearchParams
Expand Down Expand Up @@ -1363,9 +1363,8 @@
return opts;
}

var issimple = (Array.from(body.entries())
.every((x) => typeof x[1] === "string"));
if (!issimple) {
if (typeof body === "string" ||
!Array.from(body.entries()).every((x) => typeof x[1] === "string")) {
opts.body = body;
return opts;
}
Expand All @@ -1382,9 +1381,21 @@

var url = batch[0].url;
var method = batch[0].method;
var data = batch.reduce(function(acc, req) {
return mergeParams(acc, req.opts.data);
}, new FormData());
var data;

let json = getattr(batch[0].el, 'ts-json');

if (json) {
if (batch.length > 1) {
throw extraerr('Cannot batch json requests', {batch});
}
data = json;
batch[0].opts.headers['Content-Type'] = "application/json";
} else {
data = batch.reduce(function(acc, req) {
return mergeParams(acc, req.opts.data);
}, new FormData());
}

var qs = method == 'GET' ? new URLSearchParams(data).toString() : null;
var body = method != 'GET' ? data : null;
Expand Down
19 changes: 19 additions & 0 deletions www/api/ts-json.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
title: ts-json
----

# `ts-json` {.text-center}

The `ts-json` attribute is designed to handle multi-level nested data
structures in JSON format that are not possible with `ts-data`.

When a request is triggered, TwinSpark will use the `ts-json` attribute
to directly parse the JSON string from the originating element and will
set the `Content-Type=application/json` request header.

There are a few limitations to note with `ts-json` compared to `ts-data`:
- Attributes under `ts-json` do not merge.
Each `ts-json` represents a standalone dataset.
- Requests utilizing `ts-json` cannot be batched.


{{ template "examples" . }}
1 change: 1 addition & 0 deletions www/api/ts-req.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ with help of [ts-swap-push]({{ $.Rel "/api/ts-swap-push/" }}).
- [ts-req-strategy]({{ $.Rel "/api/ts-req-strategy/" }}) to deal with multiple requests from a single location.
- [ts-req-history]({{ $.Rel "/api/ts-req-history/" }}) to change URL after request.
- [ts-data]({{ $.Rel "/api/ts-data/" }}) to append data to a request.
- [ts-json]({{ $.Rel "/api/ts-json/" }}) to append data as a JSON string.
- [ts-req-batch]({{ $.Rel "/api/ts-req-batch/" }}) to combine multiple requests into a single one.


Expand Down
36 changes: 36 additions & 0 deletions www/examples/260-json.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
id: json
title: Request JSON API
tags: ts-json
----
<p>
Simple <code>POST</code> request with JSON body.
</p>

<div class="card example">
<div class="card-header">
<h5 class="d-inline mr-2">Demo</h5>
<button class="btn btn-link btn-sm reset">Reset</button>
<button class="btn btn-link btn-sm source">View Source</button>
</div>

<p class="card-body">
<a href="/data"
ts-json="{&quot;user&quot;:{&quot;name&quot;:&quot;Sanya&quot;}}"
ts-req
ts-req-method="post">Send!</a>
</p>

<script>
XHRMock.post("/data", function(req, res) {
return res.status(200)
.body(
'received: <span>' + req.body() + '</span>');
});
test(async (el, t) => {
el.$('a').click();
await t.delay(1);
let res = decodeURIComponent(el.$('span').innerText);
t.assert(res == '{"user":{"name":"Sanya"}}=');
});
</script>
</div>

0 comments on commit 90b2e78

Please sign in to comment.