Connect learningml-editor with lml-scratch

We have already seen in a previous post that the LearningML platform consists of two applications:

  • the Machine Learning model editor (learningml-editor) and
  • the program editor (lml-scratch).

In that same post, it was explained how to set up a development environment to be able to work locally in the construction of the applications.

However, there is a small detail to resolve to have a complete development environment: connect both applications so that the Machine Learning (ML) models that are built in lml-editor can be used in the lml-scratch blocks.

Indeed, if you try to do the following in your development environment:

  • run both applications on their respective development servers,
  • build an ML model with learningml-editor and
  • open the programming editor by clicking on the kitten button,

You will see that even though lml-scratch opens, the ML templates are not available. Why does this happen? How can we fix it? These will be the questions that we will answer in this post.

Why is the ML template not available in the Scratch programming editor?

The strategy that I have used to be able to use the model built with learningml-editor in lml-scratch, is based on two mechanisms offered by web browsers: The LocalStorage and the Broadcast Channel. The first is used to store data in the browser that can be accessed by applications that run in different tabs. While the second is used to send messages between applications that also run in different browser tabs.

When a new model is created with the learningml-editor, it places information about the type of model that was created in the LocalStorage, so that lml-scratch knows which Machine Learning blocks can use it. On the other hand, when a Machine Learning block is used in lml-scratch (for example a block to classify a text) it sends a message to lml-editor requesting the result. When lml-editor receives it, it performs the operation (for example classifying the text) and returns it to the block that requested it.

But it turns out that the LocalStorage and Broadcast Channel mechanisms only work between browser tabs that have been loaded from the same domain. And this is where the problem lies: the learningml-editor and lml-scratch development servers are raised on different ports, so that the first application is accessed from http://localhost: 4200, and the second from http:// localhost: 8601. And these two urls are considered by the web browser as different domains. Go shit, right?

How can we overcome this problem?

Well, it is clear that the only way to solve the problem is by serving both applications from the same domain. How can we do it? We have two possibilities:

  • Create a dropdown for each one of the application (both applications are static, that is, they are composed only of HTML, Javascript and CSSs code), and deploy them on a web server (apache or nginx, for example) so that both are served from the same domain (for example: http://my.domain/learningml and http://my.domain/scratch).
  • Place development servers behind a reverse proxy accessed from the same domain.

The first solution is suitable for a production environment but it is not operative in a development environment, since we would have to rebuild the dropdowns and put them in place every time we make a modification to the code and want to check how it works.

So we only have the second :-). Let’s see what it consists of in more detail.

A reverse proxy is nothing more than a server that makes queries to different servers, according to the url requested by the client (here client means web browser). Then, it returns the response obtained from the server to the client as if it had built it itself. That is to say, the client does not know all this hodgepodge that I just told. The following diagram helps to understand the operation of a reverse proxy.


What interests us about this gossip is that requests that arrive with the same domain but with different routes, can be resolved on servers that listen on different ports. In this way, for the client that makes the original request, all the responses come from the same domain, which is what we try to achieve so that the web browser (that is, the client) allows us to use the LocalStorage and Broadcast Channel mechanisms.

There are many solutions for deploying a reverse proxy. I will tell the one I use for the development of LearningML, based on nginx, which is enough to work on problems that require connection between learningml-editor and lml-scratch in development.

The solution is as simple as installing an nginx server, and configuring it (nginx.conf file) as follows:

worker_processes  1;
events {
    worker_connections  1024;
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       8080;
        server_name  localhost;
        proxy_buffering off;
        location / {
            proxy_pass http://localhost:4200/;
        location /scratch/ {
            proxy_pass http://localhost:8601/;
    include servers/*;

Notice that the interesting part is in the server section. It means that when the proxy server receives a request http://localhost:8000 /, consult the learningml-editor development server (remember that it responds to http://localhost:4200), and return the result to the client . And that when you receive an http://localhost:8000 / scratch request, consult the lml-scratch development server (remember that it responds to http://localhost: 8601), and return the result to the client (that is, to the Web navigator).

In this way we have achieved that the client receives the two applications: learningml-editor and lml-scratch from the same domain, namely: localhost: 8080, and therefore, that the LocalStorage and Broadcast Channel mechanisms work, necessary for both applications communicate.

And that’s it. This is the solution I came up with for the LocalStorage and Broadcast Channel mechanisms to work in my development environment. I don’t know if there will be a simpler one. So if any of you think of it, please don’t hesitate to tell me. In any case, it must be taken into account that normally each application works independently, and in that case it is not necessary to use the reverse proxy. Only when we are involved with problems related to the use of the Machine Learning model from lml-scratch, will it be necessary to use it.