Flutter for JS devs – LLF #6

Hey there 👋

I’m back with another entry to this series, so… Javascript right? We all love and hate it, yet have no choice but to use it if we want to create interactive websites (kinda). As a result, many developers know Javascript or have at least…


This content originally appeared on DEV Community and was authored by Keff

Hey there 👋

I'm back with another entry to this series, so... Javascript right? We all love and hate it, yet have no choice but to use it if we want to create interactive websites (kinda). As a result, many developers know Javascript or have at least used it on some occasion.

Consider this post as a comparison between some common aspects of both JS and Dart applications (like async code, handling lists/arrays).

Table Of Contents

Entrypoints

The first step to creating an app is launching/starting it. In dart, an entry-point function is required for all applications, in contrast to Javascript where it's up to you to define such a function. Note that if you use a framework it might require you to define an entry-point of some sort.

Let's see how Dart does it and then show some examples of how we do that in javascript and some frameworks.

Dart

In dart, all applications are required to start with a main() function.

void main() {
    // Your initial code would go here
}

Flutter

In flutter, we are also required to define a main() function. But to start the app we must call the runApp() function. This will bootstrap and start our app:

void main() {
    runApp(const MyApp());
}

Javascript

Javascript is not as strict and doesn't force us to write a main function or any kind of entry-point really. Some might start directly when the script loads, or maybe wait until the page is fully loaded. Others might only start when a button is clicked and so on.

When script loads:

function startHere() {
    // Your initial code would go here
}

startHere(); // Called when script is loaded

When page loads:

function startHere() {
    // Your initial code would go here
}

document.addEventListener('load', () => {
    // Called when the page fully loaded all the HTML and external resources
});

Angular

Angular does not require us to define an entry-point function, but it requires us to create a main file where we will bootstrap/start our application. That file would look something like this:

// imports...

platformBrowserDynamic()
    .bootstrapModule(AppModule)
    .catch(err => console.error(err));

Angular uses TypeScript but it's the same drill.

React Native

React native somewhat forces you to create an entry-point in the form of a React Component.

import React from 'react';
import { Text, View } from 'react-native';

const HelloWorldApp = () => {
  return (
    <View
      style={{
        flex: 1,
        justifyContent: "center",
        alignItems: "center"
      }}>
      <Text>Hello, world!</Text>
    </View>
  )
}
export default HelloWorldApp;

Logging

Dart does not offer such a variety of logging possibilities as the Javascript console. We are limited to just a single method print, without adding external packages (like logger).

Dart

var example = '"I will, I do, I can, I should could do, yeh"';
print('I can only log a single string, but can easily interpolate variables like this: $example');

JavaScript

let example = '"I will, I do, I can, I should could do, yeh"';
console.log('I can only log more than a single string, ', `but can easily interpolate variables like this: ${example}`);

Functions

Javascript

// Regular function
function canFly(player) {
    return player.hasWings && !player.isAChicken;
}

// Arrow function
const canRespawn = (player) => player.isInmortal;

Dart

canFly(Player player) {
    return player.hasWings && !player.isAChicken;
}

// or specifying the type
bool canFly(Player player) {
    return player.hasWings && !player.isAChicken;
}

// Arrow function
bool canRespawn = (Player player) => player.isInmortal;

Boolean checks

In Javascript 0, null, undefined, an empty string ('') are all evaluated as false. And 1 and any other non-null value is evaluated as true.

Just a meme image on javascript bool checks

Dart only considers the boolean value true as true. So let's have a close look at how to perform some common checks:

Javascript

let undefinedValue = undefined;
let nullValue = null;
let value = 0;
let emptyString = '';

if(!undefinedValue) return;
if(!nullValue) return;
if(!value) return;
if(!emptyString) return;
  • 0, null, undefined, and '' are all being treated as false.

Dart

var nullValue = null;
int value = 0;
String emptyString = '';

if(nullValue == null) return;
if(value == 0) return;
if(emptyString.isEmpty) return;

As you can see, in Dart we must implicitly check if it's a certain value. Nothing is treated as a boolean, except booleans themselves (makes sense).

  • We must use the == equality operator to implicitly check for null, 0, and other values
  • For empty string we can use the built-in isEmpty() method

Futures/Promises

Both Javascript and Dart support single-threaded execution. Javascript offers the Promise object to handle this, while in Dart we use Future objects. These classes represent the eventual completion or failure of some operation.

We commonly use Futures and Promises objects when calling remote APIs via HTTP requests, as they take a long time to complete. Synchronously doing this operation would freeze the application until the operation either fails or completes.

Javascript


function answerOfLife() {
    const url = 'https://answeroflife.ai/give-it-to-me';
    return fetch(url)
        .then(result => result.json());
}

const result = answerOfLife()
    .then(result => result.answer)
    .catch(error => console.error(error));

Dart

import 'package:http/http.dart' as http;
import 'dart:convert';

Future<Response> answerOfLife() {
    const url = 'https://answeroflife.ai/give-it-to-me';
    return http.get(url)
        .then((response) =>  jsonDecode(response.body));
}

void main() {
    var result = answerOfLife()
        .then((response) => response.answer)
        .catchError((error) => print(error));
}

Did you know that you can create Web Apps with Flutter?

It seems it's not 100% ready for big scale applications, though it does the job with some work on our part.

Async/Await

If you are familiar with Javascript async/await, Dart is almost exactly the same. We mark the function with the async keyword, then we can use the await keyword to wait for promises/futures to complete.

Javascript


function answerOfLife() {
    const url = 'https://answeroflife.ai/give-it-to-me';
    return fetch(url)
        .then(result => result.json());
}

async function main() {
    try {
        const result = await answerOfLife().then(result => result.answer);
    } catch(e) {
        console.error(error);
    }
}

Dart

import 'package:http/http.dart' as http;
import 'dart:convert';

Future<Response> answerOfLife() {
    const url = 'https://answeroflife.ai/give-it-to-me';
    return http.get(url)
        .then((response) => jsonDecode(response.body));
}

void main() async {
    try {
        const result = await answerOfLife().then(result => result.answer);
    } catch(e) {
        print(error);
    }
}

Arrays/Lists

Dart handles arrays quite similarly to javascript, with some differences. Let's take a look at some of the most common list operations.

Creating arrays

Dart

// Typed list
List<int> steps = [1, 2, 4, 8, 16, 32, 64];

// Untyped list
List stepsAndBabyNames = [1, 2, 4, 'Jonathan', 8, 'Joseph', 16, 32, 'Tommy', 64];

Javascript

const steps = [1, 2, 4, 8, 16, 32, 64];
const stepsAndBabyNames = [1, 2, 4, 'Jonathan', 8, 'Joseph', 16, 32, 'Tommy', 64];

Iterating arrays

Dart

// Using for-in loop
for(var step in steps) {
    print('Step: $step');
}

// Clasic for 
for(int i = 0; i < steps.length; i++) {
    print('Step: ${steps[i]}');
}

// forEach
steps.forEach((step) => print('Step: $step'));

Javascript

// Using for-in loop
for(let step in steps) {
    console.log(`Step: ${step}`);
}

// Clasic for 
for(let i = 0; i < steps.length; i++) {
    console.log(`Step: ${steps[i]}`);
}

// forEach
steps.forEach((step) => console.log(`Step: $step`));

Map items

Dart

steps = steps.map((step) => step * step).toList();

In dart we need to call toList to convert back to a List, as map returns a lazy Iterable (docs))

Javascript

steps = steps.map((step) => step * step);

Filter items

Dart

steps = steps.where((step) => step > 16).toList();

Javascript

steps = steps.filter((step) => step > 16);

Get a part of the list

Dart

steps.sublist(2, 4);

Javascript

steps.splice(2, 4);

Item exists

Dart

steps.contains(16);

Javascript

steps.indexOf(16) != -1;
steps.includes(16);

Find index of item

Dart

steps.indexOf(16);

Javascript

steps.indexOf(16);

Find single item

Dart

steps.firstWhere((step) => step == 16);

Javascript

steps.find((step) => step == 16).toList();

Has items

Dart

steps.isNotEmpty;

Javascript

steps.length > 0;

Maps/Objects

Most languages offer some sort of data structure to create unstructured data, dart is not different and offers the Map type.

Creating maps

Dart

Map<String, dynamic> info = {
    'name': 'Samuel',
    'age': 27,
};

Javascript

const info = {
    name: 'Samuel',
    age: 27,
};

Serializing/Deserializing JSON

Dart

import 'dart:convert';

Map<String, dynamic> info = {
    'name': 'Samuel',
    'age': 27,
};

var encodedString = json.encode(info);
var decodedMap = json.decode(infoString);

Javascript

const info = {
    name: 'Samuel',
    age: 27,
};

const encodedString = JSON.stringify(info);
const decodedMap = JSON.parse(infoString);

Running an app

Running apps differs from language to language, and from framework to framework.

Flutter

Let's first see how we do it in flutter:

  • Using the run utility in the IDE
  • Executing flutter run in the project root

React Native

In react native we:

  • use npm script npm run
  • or yarn npm run

Angular

  • Run ng serve in the project root
  • Execute npm start

Learning more

Summary

As seen in the post, Javascript and Dart have quite a few things in common. But differ in some aspects, such as handling booleans or working with arrays. This post just scratches the surface so let me know if you would like a follow-up!

If you found this post useful, please consider checking my previous post. It's a similar format to this one but comparing the theming/styling aspects of Flutter against CSS.

And as always, thanks for reading. And remember to comment if you have any suggestions, doubts, or something you would like me to cover in these posts.


This content originally appeared on DEV Community and was authored by Keff


Print Share Comment Cite Upload Translate Updates
APA

Keff | Sciencx (2021-10-11T13:39:19+00:00) Flutter for JS devs – LLF #6. Retrieved from https://www.scien.cx/2021/10/11/flutter-for-js-devs-llf-6/

MLA
" » Flutter for JS devs – LLF #6." Keff | Sciencx - Monday October 11, 2021, https://www.scien.cx/2021/10/11/flutter-for-js-devs-llf-6/
HARVARD
Keff | Sciencx Monday October 11, 2021 » Flutter for JS devs – LLF #6., viewed ,<https://www.scien.cx/2021/10/11/flutter-for-js-devs-llf-6/>
VANCOUVER
Keff | Sciencx - » Flutter for JS devs – LLF #6. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/10/11/flutter-for-js-devs-llf-6/
CHICAGO
" » Flutter for JS devs – LLF #6." Keff | Sciencx - Accessed . https://www.scien.cx/2021/10/11/flutter-for-js-devs-llf-6/
IEEE
" » Flutter for JS devs – LLF #6." Keff | Sciencx [Online]. Available: https://www.scien.cx/2021/10/11/flutter-for-js-devs-llf-6/. [Accessed: ]
rf:citation
» Flutter for JS devs – LLF #6 | Keff | Sciencx | https://www.scien.cx/2021/10/11/flutter-for-js-devs-llf-6/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.