This script is loaded correctly, it basically implements some fancy charts from chartjs.
In the javascript file of the xblock e.g. “frag.add_javascript(self.resource_string(“static/js/src/myxblock.js”))”, i define the chart by following the documentation in Introduction · Chart.js documentation, as.
let plot = new Chart(…).
The problem is when I load the xblock in the demo course, where I get an error in the console:
I’m not sure, it could be any number of things. Perhaps in the HTML, your JavaScript is appearing before the <script> tag that loads Chart.js, so Chart.js is not loaded yet?
Instead of loading it via add_javascript_url, you could try using requirejs, which is available already in the XBlock JS runtime environment.
window.RequireJS.require(['https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.min.js'], () => {
const plot = new Chart(...);
});
Even better would be to use Webpack or Rollup or TypeScript to transpile and bundle your XBlock’s code and dependencies into a single minified, tree-shaken file.
However, I was learning about what you said about transpiling the XBlock with Webpack or others, but I can’t manage to understand how it works. What is exactly the process of transpiling the XBlock and create a tree-shaken file? Where can I find documentation on how to do it?
My problem now is that my XBlock works good in the SDK server but not in the LMS. For example, my javascript file should enter this method when the page is loaded, using
It’s how I think XBlock JavaScript should be done going forward, but as far as I know, nobody has yet done it that way. So it would require some innovation and exploration. I’ve been hoping to prepare a demo of that (or convert an existing XBlock to do that) one of these days, but it’s unfortunately been on the back burner for a while.
That said, Ramshackle is a Studio plugin that I created, and it uses TypeScript to do that (transpile the source code and bundle in all the requirements like React, producing a single .js file; it’s done with the make js-watch command). So I’d likely use a very similar approach for an XBlock.
Using window.onload in that manner is not dependable, because the XBlock is often (always?) loaded “lazily”, after the window.onload event has already fired.
Instead, your JavaScript code should contain some main function like:
function MyBlock(runtime, element, configuration) {
console.log("Some functionality");
}
and then in the python student_view, you tell the runtime to run that function when the block loads, like this:
configuration = {} # Optional data to pass from python to JavaScript
fragment.initialize_js('MyBlock', configuration)
return fragment
Check the source code of almost any XBlock for an example.