Skip to content

Commit 3a8d7ef

Browse files
committed
Handle calling a function in a JavaScript module, not just a function.
1 parent c38e11a commit 3a8d7ef

File tree

4 files changed

+85
-1
lines changed

4 files changed

+85
-1
lines changed

django_unicorn/static/js/component.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,38 @@ export class Component {
121121
* @param {Array} calls A list of objects that specify the methods to call.
122122
*
123123
* `calls`: [{"fn": "someFunctionName"},]
124+
* `calls`: [{"fn": "someFunctionName", args: ["world"]},]
125+
* `calls`: [{"fn": "SomeModule.someFunctionName"},]
126+
* `calls`: [{"fn": "SomeModule.someFunctionName", args: ["world", "universe"]},]
127+
*
128+
* Returns:
129+
* Array of results for each method call.
124130
*/
125131
callCalls(calls) {
126132
calls = calls || [];
133+
const results = [];
127134

128135
calls.forEach((call) => {
129-
this.window[call.fn](...call.args);
136+
let functionName = call.fn;
137+
let module = this.window;
138+
139+
call.fn.split(".").forEach((obj, idx) => {
140+
// only traverse down modules to the first dot, because the last portion is the function name
141+
if (idx < call.fn.split(".").length - 1) {
142+
module = module[obj];
143+
// account for the period when slicing
144+
functionName = functionName.slice(obj.length + 1);
145+
}
146+
});
147+
148+
if (call.args) {
149+
results.push(module[functionName](...call.args));
150+
} else {
151+
results.push(module[functionName]());
152+
}
130153
});
154+
155+
return results;
131156
}
132157

133158
/**

example/unicorn/components/js.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ class JsView(UnicornView):
1616
def call_javascript(self):
1717
self.call("callAlert", "world")
1818

19+
def call_javascript_module(self):
20+
self.call("HelloJs.hello", "world!")
21+
1922
def get_now(self):
2023
self.select2_datetime = now()
2124

example/unicorn/templates/unicorn/js.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,21 @@
77
function callAlert(name) {
88
alert("hello, " + name);
99
}
10+
11+
var HelloJs = (function() {
12+
var self = {};
13+
14+
self.hello = function(name){
15+
alert("Hello " + name)
16+
}
17+
18+
return self;
19+
}());
1020
</script>
1121

1222
<h2>
1323
<button unicorn:click="call_javascript">Component view calls JavaScript</button>
24+
<button unicorn:click="call_javascript_module">Component view calls JavaScript module</button>
1425
</h2>
1526

1627
<div>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import test from "ava";
2+
import { getComponent } from "../utils.js";
3+
4+
test("callCalls with function name", (t) => {
5+
const functionName = "someFunction";
6+
const component = getComponent();
7+
8+
component.window[functionName] = () => {
9+
return true;
10+
};
11+
12+
const actual = component.callCalls([{ fn: functionName }]);
13+
t.deepEqual(actual, [true]);
14+
});
15+
16+
test("callCalls with function name and arg", (t) => {
17+
const functionName = "someFunction";
18+
const component = getComponent();
19+
20+
component.window[functionName] = (argOne) => {
21+
return `${argOne}!!`;
22+
};
23+
24+
const actual = component.callCalls([{ fn: functionName, args: ["great"] }]);
25+
t.deepEqual(actual, ["great!!"]);
26+
});
27+
28+
test("callCalls with module and arg", (t) => {
29+
const component = getComponent();
30+
31+
component.window.SomeModule = (() => {
32+
const self = {};
33+
34+
self.someFunction = (name) => {
35+
return `${name}!`;
36+
};
37+
38+
return self;
39+
})();
40+
41+
const actual = component.callCalls([
42+
{ fn: "SomeModule.someFunction", args: ["howdy"] },
43+
]);
44+
t.deepEqual(actual, ["howdy!"]);
45+
});

0 commit comments

Comments
 (0)