Integrate Blockly to Angular 4 application

1,277 views
Skip to first unread message

Panos Post

unread,
Aug 24, 2017, 5:17:23 AM8/24/17
to Blockly
I saw the solutions in some other thread but i will write some guidelines here for future reference
here are all the steps i followed to integrate blockly with my angular 4 application:

1) add all blockly files to the assets sections in the angular-cli.json

2) in the code.js file or all the Blocky code is add the following line of code

this.Code = Code;


 
where the Code object is where all the Blockly logic and functions are implemented. (find the code.js file and u will understand)

3)In your angular component  add this lines

declare var Code:any;


import * as code2js from 'assets/js/code2.js';



so your component can have access to the javascript Code Object i mentioned in step 3

4) in the template of your component add all the html of the blockly (of course u can make changes as you llike)
and also in the css of your component add the css of the blockly. BUT DONT PUT THE TOOLBOX XML PART you will add it in the next step with another way
so in order for your template not to give any errors do not put the xml tags at all just pure html
with an extra line

<div id="toolbox" [outerHTML]="xml"></div>


this instead of the xml i repeat

5) In your component import this too libraries

import { DomSanitizer, SafeHtml } from '@angular/platform-browser';



add these class fields

xml: SafeHtml;
block
: SafeHtml;
toolbox
: any = {toolbox: document.getElementById('toolbox')};


and the constructor :

constructor(sanitizer: DomSanitizer,private route: ActivatedRoute) {
   
 
this.xml = sanitizer.bypassSecurityTrustHtml(
 
`<xml id="toolbox" style="display: none">
    <category name="%{BKY_CATVARIABLES}" colour="%{BKY_VARIABLES_HUE}">
      <block type="variables_set"></block>
      <block type="variables_get"></block>
    </category>
    <category name="%{BKY_CATLOGIC}" colour="%{BKY_LOGIC_HUE}">
      <block type="controls_if"></block>
      <block type="logic_compare"></block>
      <block type="logic_operation"></block>
      <block type="logic_negate"></block>
      <block type="logic_boolean"></block>
    </category>
    <category name="%{BKY_CATMATH}" colour="%{BKY_MATH_HUE}">
      <block type="math_number"></block>
      <block type="math_arithmetic">
        <value name="A">
          <shadow type="math_number">
            <field name="NUM">1</field>
          </shadow>
        </value>
        <value name="B">
          <shadow type="math_number">
            <field name="NUM">1</field>
          </shadow>
        </value>
      </block>
    </category>
    <category name="%{BKY_CATTEXT}" colour="%{BKY_TEXTS_HUE}">
      <block type="text"></block>
      <block type="text_print">
        <value name="TEXT">
          <shadow type="text">
            <field name="TEXT">abc</field>
          </shadow>
        </value>
      </block>
    </category>  
  </xml>`
);
 
 
this.block = `<div   id="blocklyDiv" style="margin-left:15em;margin-top:4em;height: 710px; width: 1000px;display:none;overflow:hidden;"></div>`;


 
}


and also use ngAfterViewInit():

ngAfterViewInit(){
  code2js
.Code.init();
  code2js
.Code.activeRule=this.rule;
 
}

i do this because i have nagivation links on my app so when i switch to another component blockly content area is lost
so i found this work around.
also because of this issue i commented out  in the code.js 

window.addEventListener('load', Code.init);

because i do not need the initialization to start on the load of the page, since the blockly component is not on the landing of the page

So these are my steps for the angular blockly 100% integration (well the point is that u dont need to change the blockly logic to typescript but to use the javascript logic through the Code object in the code.js)
I hope my steps are clear enought
Enjoy guys







Panos Post

unread,
Aug 24, 2017, 5:23:48 AM8/24/17
to Blockly
and also i do not use node-blockly or something similar, just the regular javascript code given by google.

Ariel Montero

unread,
Sep 7, 2017, 12:42:21 PM9/7/17
to Blockly
I have a question.. 

In angular-cli.json i added this files. 

"./assets/blockly/blockly_compressed.js",
"./assets/blockly/blocks_compressed.js",
"./assets/blockly/javascript_compressed.js",
"./assets/blockly/msg/js/en.js",



But, when can I add the code on step 2 

Regards. 

Panos Post

unread,
Sep 12, 2017, 2:46:27 AM9/12/17
to Blockly

the code.js also goes to the cli.json
you can put it also in the assets folder like u did with the other 
blockly_compressed etc..
the line
this.Code = Code;

it should be the in the code.js file, so you can use it in your angular Application, in the same way you use jquery.
you can also do this with the this.Blockly = Blockly; so you can use the blockly functions directly with your angular app

Vanessa P. Araya

unread,
Nov 13, 2017, 8:52:47 PM11/13/17
to Blockly
Hello!

Thank you very much for these instructions!

I have a couple of questions:

1) In step 5 you put:

code2js.Code.activeRule=this.rule;

Where this.rule come from?

2) I'm having the following error:

ERROR TypeError: Cannot read property 'options' of null
    at Object.webpackJsonp.../../../../../src/assets/blockly/code2.js.Code.initLanguage (code2.js:477)
    at Object.webpackJsonp.../../../../../src/assets/blockly/code2.js.Code.init (code2.js:355)
    at MysiteComponent.webpackJsonp.../../../../../src/app/mysite/mysite.component.ts.MysiteComponent.ngAfterViewInit (mysite.component.ts:68)
    at callProviderLifecycles (core.es5.js:11176)
    at callElementProvidersLifecycles (core.es5.js:11147)
    at callLifecycleHooksChildrenFirst (core.es5.js:11131)
    at checkAndUpdateView (core.es5.js:12259)
    at callViewAction (core.es5.js:12599)
    at execEmbeddedViewsAction (core.es5.js:12557)
    at checkAndUpdateView (core.es5.js:12252)

Any idea of why this is happening?

Thank you very much for your help!
Vanessa

Panos Post

unread,
Dec 8, 2017, 6:48:40 AM12/8/17
to Blockly
this code2js.Code.activeRule=this.rule; is useless dont use it
also for the second question 
check the code.js line 477

Vanessa P. Araya

unread,
Dec 11, 2017, 7:46:31 AM12/11/17
to blo...@googlegroups.com
Ok, thanks!

--
You received this message because you are subscribed to a topic in the Google Groups "Blockly" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/blockly/JOYiM83VhSE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to blockly+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

yashk...@nexteducation.in

unread,
Feb 13, 2018, 1:33:52 AM2/13/18
to Blockly
Where i can find this code.js file

rbu...@nfbconsulting.com

unread,
May 4, 2018, 6:37:20 PM5/4/18
to Blockly
I see these guidelines for Angular 4. Are their guidelines for AngularJS? I've had some success by having the xml as a template literal however it still doesn't work just yet.

Warmly,

Ryan Busby

Nithin Biliya

unread,
Jul 22, 2019, 12:09:08 AM7/22/19
to Blockly

I was able to setup with the config mentioned below. I have also written a blog to explain this in details here - Integrate Google Blockly with Angular


install blockly with npm -

npm install git://github.com/google/blockly.git#1.20190419.0


included below files in scripts section of angular.json file -

            "scripts": [

              "node_modules/blockly/blockly_compressed.js",

              "node_modules/blockly/blocks_compressed.js",

              "node_modules/blockly/msg/js/en.js",

              "src/assets/blockly/custom_blocks.js"

            ]


added below lines in my component html file -

      <div id="blocklyDiv" style="width: 100%; height: 100%"></div>

      <xml id="toolbox" style="display: none">

        <category name="Control" colour="120">

          <block type="controls_if"></block>

          <block type="controls_repeat_ext" disabled="true"></block>

        </category>

        <category name="Text" colour="230">

          <block type="text"></block>

          <block type="text_print"></block>

        </category>

        <category name="Custom" colour="360">

          <block type="begin"></block>

          <block type="move"></block>

          <block type="end"></block>

        </category>

      </xml>


angular will throw error at this point saying it does not recognise the blockly tags. So need to use NO_ERRORS_SCHEMA in the module or can represent the toolbar XML as a string in the component TS file and use it to inject blockly.


my component TS file -


import { Component, OnInit } from '@angular/core';

import { ActivatedRoute, Router } from '@angular/router';

import { ProgramService } from '../services/program.service';

import { IProgram } from '../models/program';


declare var Blockly: any;


@Component({

  selector: 'app-program-create',

  templateUrl: './program-create.component.html',

  styleUrls: ['./program-create.component.scss']

})

export class ProgramCreateComponent implements OnInit {

  title: string;

  programName: string;

  program: IProgram;

  workspace: any;


  constructor(

    private route: ActivatedRoute,

    private programService: ProgramService,

    private router: Router

  ) {

    this.title = 'Create Visual Program';

    this.route.params.subscribe(params => {

      this.programName = params['programName'];

      this.program = this.programService.getOne(this.programName);

      if (!this.program) {

        this.program = {

          name: this.programName,

          xmlData: null

        };

      }

      console.log(

        'creating/editing the program - ',

        JSON.stringify(this.program)

      );

    });

  }


  ngOnInit() {

    this.workspace = Blockly.inject('blocklyDiv', {

      toolbox: document.getElementById('toolbox'),

      scrollbars: false

    });


    if (this.program.xmlData) {

      this.workspace.clear();

      Blockly.Xml.domToWorkspace(

        Blockly.Xml.textToDom(this.program.xmlData),

        this.workspace

      );

    }

  }


  saveProgram(): void {

    this.program.xmlData = Blockly.Xml.domToText(

      Blockly.Xml.workspaceToDom(this.workspace)

    );

    console.log('saving the program - ', JSON.stringify(this.program));

    this.programService.upsertOne(this.program);

    this.router.navigate(['listProgram']);

  }

}



Regards,

Nithin

Reply all
Reply to author
Forward
0 new messages