📜 ⬆️ ⬇️

In one harness Polymers, Dart and Firebase

Recently there was information that Google acquired the Firebase cloud service . On Habré information about Firebase is not very much, and the service looks very interesting, at least for quick prototyping or use as a buffer for active data.

FireBase is a cloud-based NoSQL database for real-time applications. That is, your data is stored in the cloud, which is ready for almost any load. Your data is instantly updated on all clients that are connected to FireBase and are subscribed to update information. There is no need to build a complex system using web sockets for data exchange between the server and clients in real time. You simply connect the JS file to the page and configure the CallBack for data change events. All - then FireBase will independently monitor the data and give it to users. Moreover, it happens almost instantly! And with FireBase, you can create web applications that do not require your own server at all . At the same time for small services using FireBase is completely free . In addition, Firebase provides installation of access rights to parts of data based on JS expressions, transactions (unlike MongoDB) and has built-in user authentication functionality via email and password, as well as authorization using third-party vendors (OAuth), such as Facebook , Twitter, GitHub, and Google.

image
')

Looking at how this works , there was a desire to rewrite the tutorial on Dart .

Dart SDK includes a package manager with more than 1,300 community packages . Among them, for example, such as AngularDart and Polymer.dart , which serve as high-level foundations for building web applications. There is also a package for working with Firebase that wraps firebase.js functionality into Dart classes using dart: js. In the same way, Dart developers can use any other JavaScript libraries with Dart.

Actually, it was with this method of using JavaScript libraries in Dart and I wanted to understand in detail.

The topic of using JavaScript libraries in Dart is presented almost exclusively as examples. In the current environment, when the native libraries under Dart are not yet under all tasks, lack of understanding of how to use the JavaScript libraries can be a major deterrent from switching to Dart. Everything else is extremely simple and looks like a very profitable investment of time for mastering a new language.

On the Dart website, a great selection of examples , experimenting with which a person with basic programming skills can fully master Dart in a couple of days. And after that you will be able to create both client and server logic in the same language, using once written class logic on the client and on the server. Dart was designed to look very familiar to programmers in languages ​​such as Java and JavaScript. For those who prefer to study on paper in Russian, you can read the book “Dart in action” . But the Russian translation of Dart Up and Running.

Unlike Java, where writing a normal GUI (graphical user interface) for practical tasks of an office user takes an average of two weeks to learn from scratch, Dart allows you to learn how to write a GUI in a couple of days. And such a GUI will perfectly solve the tasks set, work in any browser (through translation in JavaScript) and be the tool with which the end user will be able to work without problems on virtually any device with a browser.

Unlike Javascript, starting with rapid prototyping, you can easily take steps to a simple and logical module import system, strongly typed data, which greatly simplifies debugging if needed (“Different languages ​​can help you in finding errors in different ways. Unfortunately , JavaScript is located at the end of this scale, designated as “ hardly helps at all ” ”), conveniently debugging inside Dart Editor, using classes built into the language without inventing your own bikes and learning the crutches of frameworks. What is great is facilitating the use of Dart in complex projects, when a big task is decomposed and divided between several performers.

Below is the result of rewriting the tutorial on Dart, where all the nuances of interaction with JavaScript are visible.

firebase_chat.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sample app</title> <script src="packages/web_components/platform.js"></script> <script src="packages/web_components/dart_support.js"></script> <script src='https://cdn.firebase.com/js/client/1.1.1/firebase.js'></script> </head> <body> <h1>Firebase chat</h1> <div id='messagesDiv'></div> <input type='text' id='nameInput' placeholder='Name'> <input type='text' id='messageInput' placeholder='Message'> <script type="application/dart" src="firebase_chat.dart"></script> <script src="packages/browser/dart.js"></script> </body> </html> 


firebase_chat.dart
 import 'dart:html'; import 'dart:js'; InputElement messageInput; InputElement nameInput; DivElement div; JsObject myDataRef; main() { myDataRef = new JsObject(context['Firebase'], ['https://ihp8plr13um.firebaseio-demo.com/']); //  JS    Firebase,    JS  messageInput = querySelector('#messageInput') as InputElement; //   HTML   Dart  nameInput = querySelector('#nameInput') as InputElement; //   HTML   Dart  div = querySelector('#messagesDiv') as DivElement; //   HTML   Dart  messageInput.onKeyPress.listen(onMessageInputKeyPress); //   onKeyPress myDataRef.callMethod('on', ['child_added', //  JS  .on('child_added', //new JsFunction.withThis((jsThis, a, b) { //   JS -     CallBack (a, b) { var message = a.callMethod('val',[]); //  JS  .val() print(message['name'] + ':' + message['text']); displayChatMessage(message['name'], message['text']); } ]); } void onMessageInputKeyPress(KeyboardEvent e){ if (e.keyCode == 13) { var name = nameInput.value; var text = messageInput.value; var jsParams = new JsObject.jsify( {'name' : '$name', 'text' : '$text'}); //    JS  myDataRef.callMethod( 'push', [jsParams]); //  JS  .push( messageInput.value =''; }; } void displayChatMessage(String name, String text) { div.appendHtml('<em>$name:</em> $text<br />'); } 


Another addition on Dart-JS interoperability: the JS interaction approach was changed some time ago. If somewhere on SO you meet in the examples import 'package: js / js.dart' - this is already outdated .

And yes: Web Components is the only bright future for the web. Humble yourself .

This is what the same example looks like using Polymer components.

firebase_chart.html
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sample app</title> <!-- include the web_components polyfills with support for Dart. --> <script src="packages/web_components/platform.js"></script> <link rel="import" href="fc_polymer_output_div.html"> <link rel="import" href="fc_polymer_input_fields.html"> </head> <body> <h1>Firebase chat</h1> <fc-polymer-output-div fb_dblink ='https://ihp8plr13um.firebaseio-demo.com/'></fc-polymer-output-div> <fc-polymer-input-fields fb_dblink ='https://ihp8plr13um.firebaseio-demo.com/'></fc-polymer-input-fields> <!-- bootstrap polymer --> <script type="application/dart">export 'package:polymer/init.dart';</script> <script src="packages/browser/dart.js"></script> </body> </html> 


fc_polymer_output_div.html
 <script src='https://cdn.firebase.com/js/client/1.1.1/firebase.js'></script> <!-- import polymer-element's definition --> <link rel="import" href="packages/polymer/polymer.html"> <polymer-element name="fc-polymer-output-div" attributes="fb_dblink"> <template> <style> </style> <div id=messagesDiv></div> </template> <script type="application/dart" src="fc_polymer_output_div.dart"></script> </polymer-element> 


fc_polymer_output_div.dart
 import 'dart:html'; import 'package:polymer/polymer.dart'; import 'dart:js'; DivElement div; JsObject myDataRef; @CustomTag('fc-polymer-output-div') class OutputDivElement extends PolymerElement { @published String fb_dblink; OutputDivElement.created() : super.created() {} void attached() { super.attached(); myDataRef = new JsObject(context['Firebase'], [fb_dblink]); //  JS    Firebase    JS  div = $['messagesDiv'] as DivElement; //   HTML   Polymer   Dart  myDataRef.callMethod('on', ['child_added', //  JS  .on('child_added', new JsFunction.withThis((jsThis, a, b) { //     JS -     CallBack var message = a.callMethod('val',[]); //  JS  .val() print(message['name'] + ':' + message['text']); displayChatMessage(message['name'], message['text']); }) ]); } void displayChatMessage(String name, String text) { div.appendHtml('<em>$name:</em> $text<br />'); } } 


fc_polymer_input_fields.html
 <script src='https://cdn.firebase.com/js/client/1.1.1/firebase.js'></script> <!-- import polymer-element's definition --> <link rel="import" href="packages/polymer/polymer.html"> <polymer-element name="fc-polymer-input-fields" attributes="fb_dblink"> <template> <style> </style> <div> <input type='text' id='nameInput' placeholder='Name'> <input type='text' id='messageInput' placeholder='Message'> </div> </template> <script type="application/dart" src="fc_polymer_input_fields.dart"></script> </polymer-element> 


fc_polymer_input_fields.dart
 import 'dart:html'; import 'package:polymer/polymer.dart'; import 'dart:js'; InputElement messageInput; InputElement nameInput; JsObject myDataRef; @CustomTag('fc-polymer-input-fields') class InputFieldsElement extends PolymerElement { @published String fb_dblink; InputFieldsElement.created() : super.created() {} void attached() { super.attached(); myDataRef = new JsObject(context['Firebase'], [fb_dblink]); //  JS    Firebase    JS  messageInput = $['messageInput'] as InputElement; //   HTML   Polymer   Dart  nameInput = $['nameInput'] as InputElement; //   HTML   Polymer   Dart  messageInput.onKeyPress.listen(onMessageInputKeyPress); //   onKeyPress } void onMessageInputKeyPress(KeyboardEvent e){ if (e.keyCode == 13) { var name = nameInput.value; var text = messageInput.value; var jsParams = new JsObject.jsify( {'name' : '$name', 'text' : '$text'}); //    JS  myDataRef.callMethod( 'push', [jsParams]); //  JS  .push( messageInput.value =''; }; } } 


 pubspec.yaml name: Firebase_chat description: A sample Polymer Firebase app dependencies: browser: any polymer: any transformers: - polymer: entry_points: web/firebase_chat.html 


In this case, Polymer components are used to demonstrate the approach, but in real projects such decomposition allows you to effectively parallelize the development by distributing subtasks to different artists. Best of all, Polymer components are guaranteed not to conflict with each other during layout. Shadow DOM , however. And in most GUI projects, it will be possible not to write, but to assemble from ready-made components, and the layout can be done with the mouse , linking the attributes of the components to each other and getting the generated HTML (upper left corner).

You can see about the designer and his features in the video below:



Why am I all this? A rather interesting mosaic of where Google moves the web. More and more logic lives under the browser (“Hello, Chrome OS!” - in the extreme case) and can be designed as web components (including Polymer on Dart). The server can live quite smartly on the server — a successful replacement for Node.js, given that Dart in Dart VM is natively a third faster than JS, eliminates CallBack Hell's inherent software on Node.js and makes debugging much easier. Or, instead of server-side logic, Firebase can be.

And now let's speculate: how do you like this future, and how do you think that the current skills of JS + HTML + CSS + PHP will be in demand in it?

Source: https://habr.com/ru/post/244219/


All Articles