You are on page 1of 95

You have 2 free member-only stories left this month.

Sign up for Medium and get an extra one

7 JavaScript Fundamentals Every


Web Developer Should Know
Functions are values, objects inherit from other objects, and more

Cristian Salcescu Follow


Mar 24 · 4 min read
Photo by Erik Brolin on Unsplash.

In this article, we will look at what I think are some of the most important
— and unique — features of JavaScript.

1. Functions Are Independent Units of Behavior


Functions are units of behavior, but the important part here is that they are
independent. In other languages like Java or C#, functions must be
declared inside a class. This is not the case in JavaScript.

Functions can be declared in the global scope or defined inside a module as


independent units that can be reused.
2. Objects Are Dynamic Collections of Props
Objects are indeed just a collection of properties. In other languages, they
are called maps, hash maps, or hash tables.

They are dynamic in the sense that, once created, properties can be added,
edited, or deleted.

Below is a simple object defined using the object's literal syntax. It has two
properties:

const game = {
title : 'Settlers',
developer: 'Ubisoft'
}

3. Objects Inherit From Other Objects


If you are coming from class-based languages like Java or C#, you may be
used to classes inheriting from other classes. Again, that is not the case in
JavaScript.
Objects inherit from other objects called prototypes.

As mentioned earlier, in this language, objects are collections of properties.


When creating an object, it has a “hidden” property called __proto__ that
keeps a reference to another object. This referenced object is called a
prototype.

Below is an example of creating an empty object (an object with no


properties, one may say):

const obj = {};

Even if it seems to be empty and have no properties, it has a reference to the


Object.prototype object. It has the __proto__ hidden property:

obj.__proto__ === Object.prototype;


//true

On this kind of object, we can access, for example, the toString method
even if we haven’t defined such a method. How is that possible?
This method is inherited from the Object.prototype . When trying to access

the method, the engine first tries to find it on the current object, then it
looks at the properties of its prototype.

Don’t get misled by the class keyword. It is just syntactic sugar over the
prototype system trying to make the language familiar to developers
coming from a class-based language.

4. Functions Are Values


Functions are values in JavaScript. Like other values, they can be assigned
to variables:

const sum = function(x,y){ return x + y }

This is not something that can be done in any other language.

Like other values, functions can be passed to different functions or returned


from functions. Below is an example of a function returning another
function:

In the same example, we can see how the returned function from the
startsWith function is sent as an argument to the filter array method.

5. Functions Can Become Closures


Functions can be defined inside other functions. The inner function can
reference variables from the other functions.

What’s more, the inner function can reference variables from the outer
function after the outer function has executed. Below is an example of this:

The count function has access to the x variable from the createCounter

parent function even after it has been executed. count is a closure.

6. Primitives Are Treated as Objects


JavaScript gives the illusion that primitives are objects by treating them as
such. The fact is that primitives are not objects. Primitives are not
collections of properties.

However, we can call methods on primitives. For example, we can invoke


the toUpperCase method on a string:

const upperText = 'Minecraft'.toUpperCase();


console.log(upperText);
//'MINECRAFT'

A simple text like 'Minecraft' is a primitive and has no methods. JavaScript


converts it into an object using the built-in String constructor and then
runs the toUpperCase method on the newly created object.

By converting primitives to wrapper objects behind the scenes, JavaScript


allows you to call methods on them and thus treats them as objects.

7. JavaScript Is a Single-Threaded Language


JavaScript is single-threaded. That means only one statement is executed at
a specific time.

Two functions cannot execute at the same time in the main thread.

You may have heard about options for executing functions in parallel like
web workers, but workers do not share data with the main thread. They
communicate only by message passing — nothing is shared.

This makes things easier to understand and we just have to pay attention to
make functions run fast. A function that takes a long time to execute will
make the page unresponsive.

Thanks for reading. Happy coding!

Thanks to Anupam Chugh. 

Sign up for The Best of Better Programming


By Better Programming

A weekly newsletter sent every Friday with the best articles we published that week.
Code tutorials, advice, career opportunities, and more! Take a look.

Your email Get this newsletter


By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information
about our privacy practices.

Programming JavaScript Front End Development Web Development Angular

Learn more. Make Medium yours. Share your thinking.


Medium is an open platform where 170 Follow the writers, publications, and topics If you have a story to tell, knowledge to
million readers come to find insightful and that matter to you, and you’ll see them on share, or a perspective to offer — welcome
dynamic thinking. Here, expert and your homepage and in your inbox. Explore home. It’s easy and free to post your thinking
undiscovered voices alike dive into the heart on any topic. Write on Medium
of any topic and bring new ideas to the
surface. Learn more

About Help Legal


File
The File interface provides information about files and allows JavaScript in a web page to access their
content.

File objects are generally retrieved from a FileList object returned as a result of a user selecting files
using the <input> element, from a drag and drop operation's DataTransfer object, or from
the mozGetAsFile() API on an HTMLCanvasElement .

A File object is a specific kind of a Blob , and can be used in any context that a Blob can. In particular,
FileReader , URL.createObjectURL() , createImageBitmap() , and XMLHttpRequest.send() accept
both Blob s and File s.

See Using files from web applications for more information and examples.

Blob File

Constructor
File()
Returns a newly constructed File .
Instance properties
File.prototype.lastModified Read only

Returns the last modified time of the file, in millisecond since the UNIX epoch (January 1st, 1970 at
Midnight).

File.prototype.lastModifiedDate Read only


Returns the last modified Date of the file referenced by the File object.

File.prototype.name Read only


Returns the name of the file referenced by the File object.

File.prototype.webkitRelativePath Read only


Returns the path the URL of the File is relative to.

File implements Blob , so it also has the following properties available to it:

File.prototype.size Read only


Returns the size of the file in bytes.

File.prototype.type Read only


Returns the MIME type of the file.

Instance methods
The File interface doesn't define any methods, but inherits methods from the Blob interface:
Blob.prototype.slice([start[, end[, contentType]]])
Returns a new Blob object containing the data in the specified range of bytes of the source Blob .

Blob.prototype.stream()
Transforms the File into a ReadableStream that can be used to read the File contents.

Blob.prototype.text()
Transforms the File into a stream and reads it to completion. It returns a promise that resolves with
a USVString (text).

Blob.prototype.arrayBuffer()
Transforms the File into a stream and reads it to completion. It returns a promise that resolves with
an ArrayBuffer .

Specifications

Specification Status Comment

File API
Working Draft Initial definition.
The definition of 'The File interface' in that specification.

Browser compatibility
Report problems with this compatibility data on GitHub

File
Chrome 13

Edge 12

Firefox 7

Internet Explorer 10

Opera 11.5

Safari 4

WebView Android ≤ 37

Chrome Android 18

Firefox Android 7

Opera Android 11.5

Safari on iOS 3.2

Samsung Internet 1.0

File() constructor

Chrome 38

Edge 79

Firefox 28

Internet Explorer No

Opera 25

Safari 10

WebView Android 38
WebView Android 38

Chrome Android 38

Firefox Android 28

Opera Android 25

Safari on iOS 10

Samsung Internet 3.0

lastModified

Chrome 13

Edge 18

Firefox 15

Internet Explorer No

Opera 16

Safari 10

WebView Android ≤ 37

Chrome Android Yes

Firefox Android No

Opera Android No

Safari on iOS 10

Samsung Internet Yes

lastModifiedDate
Chrome 13

Edge 12

Firefox 15 — 61

Internet Explorer 10

Opera 16

Safari 6.1 — 10

WebView Android ≤ 37

Chrome Android Yes

Firefox Android No

Opera Android No

Safari on iOS 7 — 10

Samsung Internet Yes

name

Chrome 13

Edge 12

Firefox 3.6

Internet Explorer 10

Opera 16

Safari 6.1

WebView Android ≤ 37
WebView Android ≤ 37

Chrome Android Yes

Firefox Android 4

Opera Android No

Safari on iOS 7

Samsung Internet Yes

type

Chrome 13

Edge 12

Firefox 3.6

Internet Explorer 10

Opera 16

Safari 6.1

WebView Android ≤ 37

Chrome Android Yes

Firefox Android No

Opera Android No

Safari on iOS 7

Samsung Internet Yes

webkitRelativePath
Chrome 13

Edge 13

Firefox 49

Internet Explorer No

Opera No

Safari 11.1

WebView Android ≤ 37

Chrome Android 18

Firefox Android 49

Opera Android No

Safari on iOS 11.3

Samsung Internet 1.0

Full support

No support

Non-standard. Check cross-browser


support before using.
Deprecated. Not for use in new
websites.

See implementation notes.

See also
Using files from web applications
FileReader
Using the DOM File API in chrome code (for privileged code running in Gecko, such as Firefox add-
ons)

Last modified: Mar 12, 2021, by MDN contributors

Change your language


English (US) Change language
FileSystemFileEntry
Experimental
This is an experimental technology
Check the Browser compatibility table carefully before using this in production.

The FileSystemFileEntry interface of the File System API represents a file in a file system. It offers
properties describing the file's attributes, as well as the file() method, which creates a File object that
can be used to read the file.

Properties
Inherits the properties of its parent interface, FileSystemEntry , but has no properties unique to this
interface.

Methods
file()
Creates a new File object which can be used to read the file.

Obsolete methods
createWriter()
Creates a new FileWriter object which allows writing to the file represented by the file system
entry.

Basic concepts
To write content to file, create a FileWriter object by calling createWriter() . To read a file, obtain a
File object representing its contents by calling file() .

Example

The following code creates an empty file called " log.txt" (if it doesn't exist) and fills it with the text
"Meow". Inside the success callback, event handlers are set up to handle the error error and
writeend events. The text data is written to the file by creating a blob, appending text to it, and passing
the blob to FileWriter.write() .

function onInitFs(fs) {
fs.root.getFile('log.txt', {create: true}, function(fileEntry) {

// Create a FileWriter object for our FileSystemFileEntry (log.txt).


fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) {
console.log('Write completed.');
};

fileWriter.onerror = function(e) {
console.log('Write failed: ' + e.toString());
};

// Create a new Blob and write it to log.txt.


var bb = new BlobBuilder();
bb.append('Meow');

fileWriter.write(bb.getBlob('text/plain'));
}, errorHandler);

}, errorHandler);

window.requestFileSystem(window.TEMPORARY, 1024*1024, onInitFs, errorHandler);

Specifications

Specification Status Comment

File and Directory Entries API


Draft Draft of proposed API
The definition of 'FileSystemFileEntry' in that specification.

Browser compatibility
Report problems with this compatibility data on GitHub

FileSystemFileEntry

Chrome 8

Edge 79 -
x-
Firefox 50

Internet Explorer No

Opera No

Safari 11.1

WebView Android ≤ 37

Chrome Android 18

Firefox Android 50

Opera Android No

Safari on iOS 11.3

Samsung Internet 1.0

createWriter

Chrome 8

Edge 79

Firefox 50 — 52

Internet Explorer No

Opera No

Safari No

WebView Android ≤ 37

Chrome Android 18
Firefox Android 50 — 52

Opera Android No

Safari on iOS No

Samsung Internet 1.0

file

Chrome 8

Edge 79

Firefox 50

Internet Explorer No

Opera No

Safari 11.1

WebView Android ≤ 37

Chrome Android 18

Firefox Android 50

Opera Android No

Safari on iOS 11.3

Samsung Internet 1.0

Full support
No support

Non-standard. Check cross-browser


support before using.

Deprecated. Not for use in new


websites.

See implementation notes.

Uses a non-standard name.

Requires a vendor prefix or different


- name for use.
x-

See also
File and Directory Entries API
Introduction to the File System API
Last modified: Mar 15, 2021, by MDN contributors

Change your language


English (US) Change language
Home All articles

Read files in JavaScript


How to select files, read file metadata and content, and monitor read progress.
Jun 18, 2010 • Updated May 8, 2020

Kayce Basques Pete LePage


Twitter · GitHub · Glitch Twitter · GitHub · Glitch · Blog

Being able to select and interact with files on the user's local device is one of the most commonly
used features of the web. It allows users to select files and upload them to a server, for example,
uploading photos, or submitting tax documents, etc. But, it also allows sites to read and manipulate
them without ever having to transfer the data across the network.

This guide shows you how to:

Select files

Using the HTML input element


Using a drag-and-drop zone
Read file metadata
Read a file's content

Select files

HTML input element

The easiest way to allow users to select files is using the <input type="file"> element, which is
supported in every major browser. When clicked, it lets a user select a file, or multiple files if the
multiple attribute is included, using their operating system's built-in file selection UI. When the

user finishes selecting a file or files, the element's change event is fired. You can access the list of
files from event.target.files , which is a FileList object. Each item in the FileList is a
File object.

<!-- The `multiple` attribute lets users select multiple files. -->
<input type="file" id="file-selector" multiple>
<script>
const fileSelector = document.getElementById('file-selector');
fileSelector.addEventListener('change', (event) => {
const fileList = event.target.files;
console.log(fileList);
});
</script>
This example lets a user select multiple files using their operating system's built-in file selection UI
and then logs each selected file to the console.

Select files with HTML and


JavaScript
Choose Files No file chosen

Limit the types of files user can select


In some cases, you may want to limit the types of files users can select. For example, an image
editing app should only accept images, not text files. To do that, you can add an accept attribute
to the input element to specify which files are accepted.
<input type="file" id="file-selector" accept=".jpg, .jpeg, .png">

Custom drag-and-drop

In some browsers, the <input type="file"> element is also a drop target, allowing users to drag-
and-drop files into your app. But, the drop target is small, and can be hard to use. Instead, once
you've provided the core functionality using an <input type="file"> element, you can provide a
large, custom drag-and-drop surface.

Choose your drop zone


Your drop surface will depend on the design of your application. You may only want part of the
window to be a drop surface, or potentially the entire window.
Squoosh makes the entire window a drop zone.

Squoosh allows the user to drag-and-drop an image anywhere into the window, and clicking select
an image invokes the <input type="file"> element. Whatever you choose as your drop zone,
make sure it's clear to the user that they can drag-and-drop files onto that surface.

Define the drop zone


To enable an element to be a drag-and-drop zone, you'll need to listen for two events, dragover
and drop . The dragover event updates the browser UI to visually indicate that the drag-and-
drop action is creating a copy of the file. The drop event is fired after the user has dropped the
files onto the surface. Similar to the input element, you can access the list of files from
event.dataTransfer.files , which is a FileList object. Each item in the FileList is a File
object.

const dropArea = document.getElementById('drop-area');

dropArea.addEventListener('dragover', (event) => {


event.stopPropagation();
event.preventDefault();
// Style the drag-and-drop as a "copy file" operation.
event.dataTransfer.dropEffect = 'copy';
});

dropArea.addEventListener('drop', (event) => {


event.stopPropagation();
event.preventDefault();
const fileList = event.dataTransfer.files;
console.log(fileList);
});
event.stopPropagation() and event.preventDefault() stop the browser's default behavior from

happening, and allow your code to run instead. Without them, the browser would otherwise
navigate away from your page and open the files the user dropped into the browser window.

Check out Custom drag-and-drop for a live demonstration.

What about directories?

Unfortunately, today there isn't a good way to get access to a directory.

The webkitdirectory attribute on the <input type="file"> element allows the user to choose a
directory or directories. It is supported in some Chromium-based browsers, and possibly desktop
Safari, but has conflicting reports of browser compatibility.

If drag-and-drop is enabled, a user may try to drag a directory into the drop zone. When the drop
event is fired, it will include a File object for the directory, but will be unable to access any of the
files within the directory.

In the future, the File System Access API provides an easy way to both read and write to files and
directories on the user's local system. It's currently under development and only available as an
origin trial in Chrome. To learn more about it, see the File System Access API article.
Since the File System Access API is not compatible with all browsers yet, check out browser-fs-
access, a helper library that uses the new API wherever it is available, but falls back to legacy
approaches when it is not.

Read file metadata

The File object contains a number of metadata properties about the file. Most browsers provide
the file name, the size of the file, and the MIME type, though depending on the platform, different
browsers may provide different, or additional information.

function getMetadataForFileList(fileList) {
for (const file of fileList) {
// Not supported in Safari for iOS.
const name = file.name ? file.name : 'NOT SUPPORTED';
// Not supported in Firefox for Android or Opera for Android.
const type = file.type ? file.type : 'NOT SUPPORTED';
// Unknown cross-browser support.
const size = file.size ? file.size : 'NOT SUPPORTED';
console.log({file, name, type, size});
}
}

You can see this in action in the input-type-file Glitch demo.


Read a file's content

To read a file, use FileReader , which enables you to read the content of a File object into
memory. You can instruct FileReader to read a file as an array buffer, a data URL, or text.

function readImage(file) {
// Check if the file is an image.
if (file.type && file.type.indexOf('image') === -1) {
console.log('File is not an image.', file.type, file);
return;
}

const reader = new FileReader();


reader.addEventListener('load', (event) => {
img.src = event.target.result;
});
reader.readAsDataURL(file);
}

The example above reads a File provided by the user, then converts it to a data URL, and uses
that data URL to display the image in an img element. Check out the read-image-file Glitch to
see how to verify that the user has selected an image file.
Read an image file
Choose File No file chosen

Monitor the progress of a file read

When reading large files, it may be helpful to provide some UX to indicate how far the read has
progressed. For that, use the progress event provided by FileReader . The progress event
provides two properties, loaded , the amount read, and total , the total amount to read.
function readFile(file) {
const reader = new FileReader();
reader.addEventListener('load', (event) => {
const result = event.target.result;
// Do something with result
});

reader.addEventListener('progress', (event) => {


if (event.loaded && event.total) {
const percent = (event.loaded / event.total) * 100;
console.log(`Progress: ${Math.round(percent)}`);
}
});
reader.readAsDataURL(file);
}

Hero image by Vincent Botta from Unsplash

Storage

Last updated: May 8, 2020 Improve article


Reading & Processing Files with the JavaScript FileReader API
JavaScript

By Jack Misteli
Published on January 23, 2020   29.6k

While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or edited it to ensure you have an error-free
learning experience. It's on our list, and we're working on it! You can help us out by using the "report an issue" button at the bottom of the tutorial.

Reading, writing and analyzing files is an essential component of software development. For security reasons, in JavaScript, we
can’t directly access users’ files. If we had something like fs in Node.js, we could just steal documents from users!

First, to get a file from a user, we need to use an input element:

<input id="my-input" type="file" onChange="handleFileChange">

This tiny piece of code will allow our user to upload files from her machine. The  handleFileChange  function that we’ll create will
receive some information about the uploaded files, but to be able to manipulate them we need to use the  FileReader API.

Uploading Your File


Here’s a piece of code to upload a file using an HTML form.
<form enctype="multipart/form-data" action="/upload" method="post">
<input id="file-input" type="file" />
</form>

There is only so much you can get from an HTML form  POST . If you prefer to use JavaScript to make your requests you can do
something like this:

let file = document.getElementById("file-input").files[0];


let formData = new FormData();

formData.append("file", file);
fetch('/upload/image', {method: "POST", body: formData});

File Blob Properties


In many browsers, Files have Blob properties/functions. These functions allows us to read the file. We’re going to use a file
called  myFile.txt  which looks like this:

File content!

(async () => {
// .text() transforms the file into a stream and then into a string
const fileContent = await file.text();
console.log(fileContent);
// logs "File content!"

// .stream() returns a ReadableStream


const fileContentStream = await file.stream();
console.log(await streamToText(fileContentStream));
// logs "File content!"

const buffer = await file.arrayBuffer();


console.log(bufferToText(buffer))
// logs "File content!"

// .slice() allows you to get slices of the file here we take a slice of the entire file
const fileSliceBlob = file.slice(0, file.length);
// we convert to blob to a stream
const fileSliceBlobStream = await fileSliceBlob.stream();
console.log(await streamToText(fileSliceBlobStream));
// logs "File content!"

})()

// We just use this function to convert streams to text


const streamToText = async (blob) => {
const readableStream = await blob.getReader();
const chunk = await readableStream.read();
return new TextDecoder('utf-8').decode(chunk.value);
}

// Not the best way to get text from a file!


const bufferToText = (buffer) => {
const bufferByteLength = buffer.byteLength;
const bufferUint8Array = new Uint8Array(buffer, 0, bufferByteLength);
return new TextDecoder().decode(bufferUint8Array);
}

The problem is that a few important browsers don’t support the File Blob properties.

Some FileReader Code


The FileReader API is used much more broadly. As you will see, we have similar features to the File interface. We also have
additional features.

FileReader Lifecycle
There are 6 main events attached to FileReader:

loadstart: Fires when we start loading a file.

progress: Fires when the blob is read in memory.

abort: Fires when we call  .abort

error: Fires when an error occurs

load: Fires when the read is successful.

loadend: Fires when the file is loaded and if error or abort didn’t get called or if load starts a new read.

FileReader Methods
To start loading our file we have four methods:

readAsArrayBuffer(file) : Reads the file or blob as an array buffer. One use case is to send large files to a service worker.

readAsBinaryString(file) : Reads the file as a binary string

readAsText(file, format) : Reads the file as USVString (almost like a string), and you can specify an optional format.

readAsDataURL(file) : This will return a URL where you can access the file’s content, it is Base64 encoded and ready to send to
your server
Here is some code you can use to see the FileReader API in action.

<body>
<input type='file' id='input'>
<progress value="0" max="100" id="progress-bar"></progress>
<div id="status"></div>
<script>

//
document.getElementById('input').addEventListener('change', (e) => {
const file = document.getElementById('input').files[0];
if (file) {
processFile(file);
}
})

const processFile = (file) => {


// we define fr as a new instance of FileReader
const fr = new FileReader();

fr.readAsDataURL(file);
// Handle progress, success, and errors
// fr.onprogress = updateProgress;
fr.onerror = errorHandler;
fr.onabort = () => changeStatus('Start Loading');
fr.onloadstart = () => changeStatus('Start Loading');
fr.onload = ()=> {changeStatus('Loaded')};
fr.onloadend = () => loaded;
// Here you can perform some operations on the data asynchronously
fr.onprogress = setProgress;
}

// Updates the value of the progress bar


const setProgress = (e) => {
// The target is the file reader
const fr = e.target;
const loadingPercentage = 100 * e.loaded / e.total;
document.getElementById('progress-bar').value = loadingPercentage;
}

const changeStatus = (status) => {


document.getElementById('status').innerHTML = status
}

const loaded = (e) => {


changeStatus('Load ended!');
const fr = e.target
var result = fr.result;
console.log('result:')
console.log(result)
// Here we can send the result to a server for example
}

const errorHandler = (e) => {


changeStatus("Error: " + e.target.error.name)
}

</script>
</body>

You can see the code live here (open your developer console) and the source code here.

File Reader on Threads


FileReader is an asynchronous API because we do not want to block the main thread while reading files. For example, we don’t
want our UI to stop working when the browser is trying to read a very large file. However, there is a synchronous version of
FileReader called FileReaderSync. We can only use FileReaderSync in Web Workers. Web workers have their own thread so they
won’t block the main thread. FileReaderSync uses the same methods as FileReader:
FileReaderSync.readAsArrayBuffer()

FileReaderSync.readAsBinaryString()

FileReaderSync.readAsText()

FileReaderSync.readAsDataURL()

There are no event handlers because it’s synchronous.


A Beginner’s Guide to Vue 3 Composition API with Examples
Vue introduces Composition API (Function-based API) as an addition to current Options-based API. The API will be released with
Vue 3, but now you can try it with Vue 3 Composition APIadded to your Vue 2 app. In this tutorial, we’re gonna show you:

New Vue Composition API overview and comparison with classic Vue Options-based API
Examples to implement a Vue Component with new API: props, data, watchers, lifecycle hooks
Example to take advantage of new Vue 3 Composition API (function-based API): split Topics into Functions

Contents

What’s changed when Vue Composition API is added?


Options-based API vs Composition API
Use Vue 3 Composition API in current Vue 2 project
Vue setup() function
this.$refs with new Composition API
Vue Composition API examples
Vue Composition API Computed Values
Vue Composition API Watchers
Vue Composition API Lifecycle Hooks
Encapsulate logical Topics into Functions
Conclusion
Source Code

What’s changed when Vue Composition API is added?


Everything will still work as it works before. Almost things don’t change:

CLI
Template syntax
Object format
Reactivity system
Concepts of computed properties, watchers & component lifecycle
SFC format
Progressive nature of Vue framework

Options-based API vs Composition API


The difference of current Options-based API concept vs new Composition API (Function-based API) concept is the way we think of
what a component contains:

Options-based API: A component contains types of properties/methods/options.


Composition API: A component encapsulates logical topics into functions.

Component options could become complicated to be organized and hard to maintain (monster component). A logical topic could
involve properties in props and data(), some methods, a certain hook (beforeMount/ mounted), and a watcher in watch. Hence one
single topic will be fragmented across multiple options.

With Composition API, every function, which is a part of the big component, encapsulates all the code related to the logical topic
(properties, methods, hooks, watchers). Now that smaller code (function) can be reused, and well-organized.

Use Vue 3 Composition API in current Vue 2 project


We can use new Vue 3 Composition API in our current Vue 2.x project by installing [@vue/composition-api]
(https://www.npmjs.com/package/@vue/composition-api) module.

It is so easy, just run the command:

npm install @vue/composition-api

Or

yarn add @vue/composition-api

Then import it in main.js.


import Vue from 'vue';
import CompositionApi from '@vue/composition-api';

Vue.use(CompositionApi);

Vue setup() function


[setup()](https://vue-composition-api-rfc.netlify.com/api.html#setup) is the new component option that we will use new Vue Composition
API to setup the logic (logical topics) of the component. If setup() function becomes complex, we can easily split it into multiple
functions with corresponding to logical topics.

When setup() is called?
It is called after props resolution, when an instance of the component is created.

Now look at the Vue component with setup() function:

const MyComponent = {
props: {
name: String
},
setup(props, context) {
console.log(props.name);
// context.attrs
// context.slots
// context.emit
// context.parent
// context.root
}
}

The function has 2 arguments:


– props
– context

context has properties (attrs, slots, emit, parent, root) that are corresponding to this.$attrs, this.$slots, this.$emit, this.$parent, this.$root.


We can also destructure them with the latest values even after updates:

const MyComponent = {
setup(props, { attrs }) {

function onClick() {
attrs.foo // automatically update latest value
}
}
}

*Note:this keyword is not available inside setup() function.

So this.$emit cannot be used like this:

setup() {
function onClick() {
this.$emit // not available
}
}

this.$refs with new Composition API


To get a reference to an element or component instance in the template, we use [ref](https://vue-composition-api-
rfc.netlify.com/api.html#ref) API so that setup() can return reactive and mutable object for render context.

import { ref } from '@vue/composition-api'

const MyComponent = {
setup(props) {
const name = ref('bezkoder.com')
const appendName = () => {
name.value = `hello ${props.name}`
}
return {
name,
appendName
}
},
template: `<div @click="appendName">{{ name }}</div>`
}

ref automatically unwraps to the inner value, so we don’t need to append .value in the template: {{ name }} is enough, not {{ name.value
}}.

Vue Composition API examples


In this section, we’re gonna show you examples that use new API along with old Vue2 options-based API syntax.
Vue Composition API Computed Values
Vue2 options-based API syntax:

export default {
props: {
title: String
},
computed: {
vTitle() {
return '-' + this.title + '-';
},
itemsQuantity() {
return this.items.length;
}
},
data() {
return {
items: ['This', 'is'],
};
},
}

Vue 3 Composition API syntax:

import { ref, computed } from '@vue/composition-api';

export default {
props: {
title: String
},
setup(props) {
const vTitle = computed(() => '-' + props.title + '-');

const items = ref(['This', 'is']);


const itemsQuantity = computed(() => items.value.length);

return {
vTitle,
items,
itemsQuantity,
};
}
};
With new computed API, we can create a writable ref object with get and set functions.

const count = ref(1)


const double = computed({
get: () => count.value * 2,
set: val => { count.value = val - 1 }
})

double.value = 3 // set: count.value = 3 - 1 = 2


console.log(count.value) // 2
console.log(double.value) // get: count.value * 2 = 4

Vue Composition API Watchers


This is how we use Vue2 options-based API syntax:

export default {
data() {
return {
items: ['This', 'is'],
append: ''
};
},
watch: {
items: {
handler: function(value, oldValue) {
this.append = '';
value.forEach(item => {
this.append += item + ' ';
});
},
immediate: true
}
},
}
Like watch option, we can use new Vue watch API to perform side effect everytime a state is changed.

The syntax is: watch(source, callback, options)

source: could be a getter function, a value wrapper, or an array containing the two above types (in case of watching multiple
sources)
callback: is the function like Vue2 watcher handler function, with 2 arguments: newVal, oldVal. Each argument could be an array (for
watching multiple sources): [newVal1, newVal2, ... newValN], [oldVal1, oldVal2, ... oldValN]
options (optional): is used for configuring watcher type containing: lazy, deep, flush.

For more details about WatchOption, please visit: api#watch.

import { ref, watch } from '@vue/composition-api';

export default {
setup(props) {
const items = ref(['This', 'is']);
const append = ref('');

watch(
// getter
() => items.value,
// callback
(items, oldItems) => {
append.value = '';
items.forEach(item => {
append.value += item + ' ';
});
},
// watch Options
{
lazy: false // immediate: true
}
)

return {
items,
append
};
}
};

In case we want to watch multiple sources:

watch([aRef, bRef], ([a, b], [prevA, prevB]) => {


/* ... */
})

We can also split the multiple sources watcher into smaller watchers. This helps us organize our code and create watchers with
distinct options:

watch(
// getter
() => items.value,
// callback
(items, oldItems) => {
append.value = '';
items.forEach(item => {
append.value += item + ' ';
});
},
// watch Options
{
lazy: false // immediate: true
}
)

watch(
// getter
() => todo.value.length,
// callback
(length, oldLength) => {
todoLength.value = length;
},
// watch Options
{
lazy: true // immediate: false
}
)

Vue Composition API Lifecycle Hooks


With Vue2, we implement Lifecycle Hooks functions by this way:

export default {
beforeMount() {
console.log('V2 beforeMount!')
},
mounted() {
console.log('V2 mounted!')
}
};

New Vue 3 Composition API has equivalent functions, we can use those with on prefix inside setup() function:

import { onBeforeMount, onMounted } from '@vue/composition-api';

export default {
setup() {
onBeforeMount(() => {
console.log('V3 beforeMount!');
})

onMounted(() => {
console.log('V3 mounted!');
})
}
};
You can see the mapping between Lifecycle Vue2 Options and Composition API in the following table:

Encapsulate logical Topics into Functions


Now we combine all code above into one Vue Component, you can see a complex component with multiple topics. We need to
implement logic for title, for todo, for items:

import { ref, reactive, computed, watch, onBeforeMount, onMounted } from '@vue/composition-api';

export default {
props: {
title: String,
initInput: String
},
setup(props) {
const vTitle = computed(() => '-' + props.title + '-');
const todo = ref(props.initInput);
const todoLength = ref(0);

const items = ref(['This', 'is']);


const itemsQuantity = computed(() => items.value.length);
const append = ref('');

watch(
// getter
() => items.value,
// callback
(items, oldItems) => {
append.value = '';
items.forEach(item => {
append.value += item + ' ';
});
},
// watch Options
{
lazy: false // immediate: true
}
)

watch(
// getter
() => todo.value.length,
// callback
(length, oldLength) => {
todoLength.value = length;
},
// watch Options
{
lazy: false // immediate: true
}
)

const add = () => {


if (todo.value) {
items.value.push(todo.value);
todo.value = '';
}
};

const remove = index => {


items.value.splice(index, 1);
};

onBeforeMount(() => {
console.log('V3 beforeMount!');
})

onMounted(() => {
console.log('V3 mounted!');
})

return {
vTitle,
todo,
todoLength,
items,
itemsQuantity,
append,
add,
remove
};
}
};

It comes time to take advantage of Vue Composition API: split complex component into multiple functions with corresponding to
logical topics:

import { ref, computed, watch, onBeforeMount, onMounted } from "@vue/composition-api";

function useTitle(props) {
const vTitle = computed(() => "-" + props.title + "-");
return {
vTitle
};
}

function useTodoLength(todo) {
const todoLength = ref(0);

watch(
// getter
() => todo.value.length,
// callback
(length, oldLength) => {
todoLength.value = length;
},
// watch Options
{
lazy: false // immediate: true
}
);

return {
todoLength
};
}

function useItems(todo) {
const items = ref(["This", "is"]);
const itemsQuantity = computed(() => items.value.length);
const append = ref("");

watch(
// getter
() => items.value,
// callback
(items, oldItems) => {
append.value = "";
items.forEach(item => {
append.value += item + " ";
});
},
// watch Options
{
lazy: false // immediate: true
}
);

const add = () => {


if (todo.value) {
items.value.push(todo.value);
todo.value = "";
}
};

const remove = index => {


items.value.splice(index, 1);
};

return {
items,
itemsQuantity,
append,
add,
remove
};
}

export default {
props: {
title: String,
initInput: String
},
setup(props) {
const todo = ref(props.initInput);
onBeforeMount(() => {
console.log("V3 beforeMount!");
});

onMounted(() => {
console.log("V3 mounted!");
});

return {
todo,
...useTitle(props),
...useTodoLength(todo),
...useItems(todo)
};
}
};

The results:
It works like a charm.
We can easily view each topic by its own function. Each topic has its own props, data, watchers, methods. Our component now only
need to inject these functions and return them inside its setup()function.

Fantastic!

Conclusion
Maybe you feel comfortable when using the old Vue options-based API, or maybe you don’t like to think of everything as functions
but properties/methods with OOP mindset. The creators are developing Vue, make it better year after year and give us more
options. Just try it and feel the good.

Happy learning! See you again!

Source Code
You can find the complete source code for this ‘Vue Composition Api example’ on Github.

vue-js vuejs vue javascript web-development


You have 1 free member-only story left this month. Sign up for Medium and get an extra one

Understanding Call-by-Value and


Call-by-Reference in JavaScript
Pascal Zwikirsch Follow
Feb 12 · 3 min read

Why it’s super important to understand how JavaScript handles parameters


and that it’s not purely Call-by-Reference or Call-by-Value.
Photo by Sincerely Media on Unsplash

You might know that other languages like C are using pointer arithmetic. So
when using variables you can either “point” to a certain address in memory
where the actual value of your variable is located (by reference) or have the
value directly at hand (by value). Of course, deep under the hood,
everything is stored in memory.

In JavaScript, it’s a bit different. Sure under the hood a lot of magic is
happening but for the human JavaScript developer, there is no pointer
arithmetic available.
So you might think: “Great, that pointer arithmetic stuff was super complex
anyway, so let’s just push around actual values!”

Nice thought but pretty flawed. Even though JavaScript doesn’t have any
actual pointers, like other languages, references are still existing.

Primitive Types
So let’s inspect how primitive types work:

1 // Numbers
2 (() => {
3 let a = 5;
4 let b = a;
5 a = 6;
6
7 console.log(`-- Number --`);
8 console.log(`a: ${a}`); // a: 6
9 console.log(`b: ${b}`); // b: 5
10 console.log(`\n`);
11 })();
12
13 // Strings
14 (() => {
15 let a = 'Hello';
16 let b = a;
17 a = 'HELLO';
18
19 console.log(`-- String --`);
20 console.log(`a: ${a}`); // a: HELLO
20 console.log( a: ${a} ); // a: HELLO
21 console.log(`b: ${b}`); // b: Hello
22 console.log(`\n`);
23
24 })();
25
26 // Booleans
27 (() => {
28 let a = true;
29 let b = a;
30 a = false;
31
32 console.log(`-- Boolean --`);
33 console.log(`a: ${a}`); // a: false
34 console.log(`b: ${b}`); // b: true
35 console.log(`\n`);
36
37 })();

call-by-value.js hosted with ❤ by GitHub view raw

When you run the above snippet you can see that for primitives like string ,

boolean and number types an actual copy is happening when you assign a

to b , since you can change a without changing the value of b.

So we can safely say that for primitive types: let b = a; => The VALUE of
a is being copied into the variable b.
=> This is called “Call-by-Value”, since the value itself is being set to the
new variable.

Non-primitive Types
But for non-primitive types like Object and Array types the story is a
different one.

1 // Objects
2 (() => {
3 let a = { content: 'a' };
4 let b = a;
5 a.content = 'something else';
6
7 console.log(`-- Object --`);
8 console.log(`a: ${JSON.stringify(a)}`); // a: {"content":"something else"}
9 console.log(`b: ${JSON.stringify(b)}`); // b: {"content":"something else"}
10 console.log(`\n`);
11 })();
12
13 // Nested Objects
14 (()=>{
15 let a = { arr: [] };
16 let b = Object.assign({}, a);
17 a.arr.push('a');
18
19 console.log(`-- Nested Object --`);
20 console.log(`a: ${JSON.stringify(a)}`); // a: "arr":["a"]}
21 console.log(`b: ${JSON.stringify(b)}`); // b: "arr":["a"]}
22 console.log(`\n`);
23 })();
23 })();
24
25 // Arrays
26 (() => {
27 let a = ['a'];
28 let b = a;
29 a.push('b');
30
31 console.log(`-- Array --`);
32 console.log(`a: ${JSON.stringify(a)}`); // a: ["a","b"]
33 console.log(`b: ${JSON.stringify(b)}`); // b: ["a","b"]
34 console.log(`\n`);
35 })();

call-by-reference.js hosted with ❤ by GitHub view raw

Checking out the above example you will notice that the a and b prints the
same values to the console. That is because the variable b is not really
being assigned a copy of the actual Object / Array but only a reference to it.
So a and b are “pointing”/”referencing” to the same object instead of just
containing the same value. A small but very important difference.

So we can safely say that for non-primitive types: let b = a; => The
reference that a is pointing to is copied into the variable b.

=> This is called “Call-by-Reference”, since you the reference to the non-
primitive type is being set to the new variable instead of the plain value.
Functions
Since we have now examined how variables are assigned for the different
types let’s go one step further and check if JavaScript uses Call-by-Value or
Call-by-Reference for its methods when parameters are passed into them.

Taking the next snippet as an example, where a number. and an object is


being passed into:

1 // Methods
2 (() => {
3 let a = 5;
4 let b = { a: 4 };
5
6 ((c, d) => {
7 c = 4;
8 d.a = 5;
9 })(a, b);
10
11 console.log(`-- Method --`)
12 console.log(`a: ${a}`); // a: 5
13 console.log(`b: ${JSON.stringify(b)}`); // b: {"a":5}
14 console.log(`\n`)
15
16 })();

call-by-methods.js hosted with ❤ by GitHub view raw


Here, a number and an object type variable are defined, passed into an
inline method, and are then printed to the console. The only functionality
of the inline method is to modify the passed-in parameters. So let’s run the
script and check the logs.

As you might have already assumed, due to the explanation before, the
value of a is still our initial value but the value of b was changed by the
method. So why is this the case? That’s because passing parameters into
methods is nothing different than assigning them to another variable —
declared in the method arguments — and as we could already see before for
primitives types a Call-by-Value and for non-primitive types, a Call-by-
Reference is happening.

So whenever you pass complex types like Object or Array into a method,
you should be super careful with modifying it since these changes will also
be reflected outside the scope of the method and might produce unwanted
side-effects.

Conclusion
I hope I could provide you some insights regarding Call-by-Value and Call-
by-Reference when using JavaScript and help you to understand why
certain side effects are happening if you have ever wondered why
modifying a passed-in object inside a method is also reflected in its outer
scope.

Thanks for taking the time to read my article.

If you have any questions or additions feel free to use the comment section
or hit me up on LinkedIn or Twitter to get in contact with me 😊

Thanks to Sunil Sandhu. 

JavaScript Programming Nodejs Web Development Coding

Learn more. Make Medium yours. Share your thinking.


Medium is an open platform where 170 Follow the writers, publications, and topics If you have a story to tell, knowledge to
million readers come to find insightful and that matter to you, and you’ll see them on share, or a perspective to offer — welcome
dynamic thinking. Here, expert and your homepage and in your inbox. Explore home. It’s easy and free to post your thinking
undiscovered voices alike dive into the heart on any topic. Write on Medium
of any topic and bring new ideas to the
surface. Learn more

About Help Legal


This is an archived page. It's not actively maintained.

Using the DOM File API in chrome code


If you want to use the DOM File API in chrome code, you can do so without restriction. In fact, you get one
bonus feature: you can create File objects specifying the path of the file on the user's computer. This only
works from privileged code, so web content can't do it. This protects users from the inherent security risks
associated with allowing web content free access to the contents of their disks. If you pass a path to the
File constructor from unprivileged code (such as web content), an exception will be thrown.

Scope Availability
In the JSM scope File is available without needing to do anything special.

In Bootstrap scope, this must be imported in like so:

Cu.importGlobalProperties( [ "File" ] )

Accessing a file by hard-coded pathname


To reference a file by its path, you can simply use a string literal:

var file = File.createFromFileName("path/to/some/file");

Cross platform note: However using hard-coded paths raises cross platform issues since it uses a platform-
dependent path separator (here "/"). In the XUL/Mozilla platform there isn't sadly an equivalent to Java
depe de t pat sepa ato ( e e / ) t e U / o a p at o t e e s t sad y a equ a e t to Ja a
This is an
File.pathSeparator (the system-dependent archived page.
path-separator It's not).
character actively
So themaintained.
good practice is to
avoid trying to determine and to use the path separator at all. Instead, use the nsIFile::append() method as
explained in the next section.

Accessing files in a special directory


You can also use the directory service to obtain and build the path to a file to access. For example, let's say
your add-on needs to access a file in the user's profile. You can do so like this:

var dsFile = Components.classes["@mozilla.org/file/directory_service;1"]


.getService(Components.interfaces.nsIProperties)
.get("ProfD", Components.interfaces.nsIFile);

dsFile.append("myfilename.txt");

var file = File.createFromNsIFile(dsFile);

This uses the directory service to locate the profile directory (with the location key "ProfD", see below for
more details), then appends the name of the file we want to work with by calling nsIFile.append() .
Finally, we instantiate the File object by calling File.createFromNsIFile.

Other such keys as the "ProfD" key are available, check the known locations.

Notes
Starting in Gecko 8.0 (Firefox 8.0 / Thunderbird 8.0 / SeaMonkey 2.5), you can also do this in component
code.

See also
This is an archived page. It's not actively maintained.
Using files from web applications
File
nsIDirectoryService

nsIFile

Last modified: Feb 20, 2020, by MDN contributors

Change your language


English (US) Change language
This is your last free member-only story this month. Sign up for Medium and get an extra one

Why Mastering Vanilla JavaScript


Will Make You Stand Out as a
Developer
Be better than seasoned developers by having the knowledge that
many of them miss

Piero Borrelli Follow


Oct 1, 2020 · 3 min read
Photo by matthew Feeney on Unsplash.

Despite being one of the easiest languages to learn as a beginner, JavaScript


is eccentric enough to be truly hard to master. It allows you to write full-
scale programs while still scratching its surface, discouraging you from
truly understanding the language deep’s capabilities.

It’s both a simple tool and a complex set of empowering mechanics. But
what can it do for you if you truly master it?

Let’s try to answer this question.


It Frees You From Future Technology Anxieties
Remember the old technologies that used to populate our IDEs like jQuery?
They were all killed by the continuous progress of programming languages.
Yet, developers are thirsty to know more about Angular or React now,
forgetting that JavaScript is probably the only constant in this ever-
changing web world. How could it be otherwise? It’s the true language of
the web, and without it, we are doomed.

Master the language and have great fundamentals to ace any technologies
that the future might present to you because they’re nothing more than
language extensions themselves.

Better Code
I deeply encourage you to take the road less travelled and not stop when
something only works in your code but also when you know why it works
that way. A proper understanding of vanilla JS exposes you to its core
mechanics and why the language works the way it does.
You will start to see things that most developers’ eyes won’t catch. You will
gain a newfound way of looking and understanding your code, highly
increasing the chances of it being of high quality.

Interviews
In all the interviews I have done in my career, I’ve never encountered one
where core JS concepts weren’t vital to succeeding and landing the job. You
may apply for a React position and receive a lot of questions about
components, but they are simply classic JavaScript classes or functions. You
might get questions about Hooks, but they rely on closures, which are still a
vanilla JS concept.

Learn JavaScript like a true professional. Master its core in and out. Watch
it take you where other developers can’t go and make the interview game
ten times easier for you.

How You Can Learn Vanilla JS Like a Pro


Here are my recommended resources for learning vanilla JavaScript like a
pro. They are all extremely cheap or even free and will take you a long way
ahead of your peers in mastering this beautiful language.

Udemy’s best course about JavaScript, including real-world projects


and testing tools tutorials (paid)

Learn Modern Javascript (Build and Test Apps) - Full


Course
"Excellent course. Jonas explains the core concepts in javascript
that are usually glossed over in other courses. And…
www.udemy.com

Wes Bos’ 30-day Vanilla Js challenge (free)

JavaScript 30
Build 30 things with vanilla JS in 30 days with 30 tutorials
javascript30.com

To become a true JS ninja, a series of free ebooks about mastering


JavaScript (free)
getify/You-Dont-Know-JS
A book series on JavaScript. @YDKJS on twitter. Contribute to
getify/You-Dont-Know-JS development by creating an…
github.com

Conclusion
Whether you’re a beginner or a seasoned developer, mastering vanilla JS in
2020 will make you feel like going against the average trend. But this is the
behaviour that will gift you with unbreakable fundaments that any
interview or future framework won’t be able to break — now or in the
future.

Thanks to Zack Shapiro. 

Sign up for The Best of Better Programming


By Better Programming

A weekly newsletter sent every Friday with the best articles we published that week.
Code tutorials, advice, career opportunities, and more! Take a look.
Your email Get this newsletter
By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information
about our privacy practices.

Programming JavaScript Technology React Learning To Code

Learn more. Make Medium yours. Share your thinking.


Medium is an open platform where 170 Follow the writers, publications, and topics If you have a story to tell, knowledge to
million readers come to find insightful and that matter to you, and you’ll see them on share, or a perspective to offer — welcome
dynamic thinking. Here, expert and your homepage and in your inbox. Explore home. It’s easy and free to post your thinking
undiscovered voices alike dive into the heart on any topic. Write on Medium
of any topic and bring new ideas to the
surface. Learn more

About Help Legal


Sign in to medium.com with Google

TINI UMOH
tiniumoh@gmail.com

Why not to build an Electron App


Continue as TINI

Prasann Shah Follow


Nov 3, 2018 · 4 min read
Sign in to medium.com with Google

TINI UMOH
tiniumoh@gmail.com

Continue as TINI

Our App almost crashing the fragile windows machine

Electron seems to be an awesome technology. The amount of apps currently


being built using electron is a testament of that. But if you see the most
successful electron apps, they are being supported by engineers solely
focused on optimising electron and making sure that Sign
the inapp doesn’t end
to medium.com withup
Google

crashing the customer’s machines.


TINI UMOH
tiniumoh@gmail.com

Imagine a startup just starting their first POC or just getting off the ground.
Continue as TINI
At this point all you want to focus on is the problem you are trying to solve.
You absolutely don’t have resources or time to solve challenges which are
not the core of your business.

Simply put if you have enough resources to focus completely on optimising


the desktop experience, electron might just work out for you. But that isn’t
the case for most of the startups I have met. They are majorly front end guys
unaware of systems complexity when dealing with high RAM utilisation or
minimising inter process communication.

In our case, we took on a challenge of building an enterprise SaaS product


using electron with 5 front end ninjas. We had enough knowledge of how to
build awesome apps using JS, React, CSS and UX magic. We were
completely unaware and unequipped for the challenges we were about to
face building an electron app.

In this article I am not going to be listing down the pros of using electron. I
will rather be focusing on the cons of electron and any desktop app in
general. This is a list of challenges i have listed down from our experiences
in building our Enterprise SaaS app in Electron. Sign in to medium.com with Google

TINI UMOH

Inter-Process Communication (IPC)


tiniumoh@gmail.com

Continue as TINI

Every data you store locally is communicated back to main process to store on disk

We build our app considering being able to work offline as our primary
goal. We used RxDB as our database and all information was synced
between our servers and the local database every few minutes. This relied
heavily on the users system to be able to write data really fast. But as it
turns out a lot of our users have crappy systems whereSign
disk read
in to writes with
medium.com are Google
extremely slow ( 5400 rpm hard drives!). This lead to the systems starting
TINI UMOH
to experience performance issues. tiniumoh@gmail.com

Continue as TINI

Consider a 4GB RAM machine with a dual core


processor with chrome, outlook, excel and an
electron app open. Needless to say, the systems
almost crashed. It became impossible for any user to
get work done.

Later we optimised the read/writes, moved the writes to background


processes, reduced the requirement on offline with storing only essential
data etc. But it took a lot of months of focused optimisation and refactoring
which we could have spent concentration on the product and the problem.

RAM Utilisation
Sign in to medium.com with Google

TINI UMOH
tiniumoh@gmail.com

Continue as TINI

Imagine Chrome open on your machine with 3 other electron apps

Electron runs a chromium process and renders your JS and HTML in the
window. Which is like running another chrome instance in a machine
which may not be able to give you enough resources.
Chromium hogs memory like crazy.
Sign in to medium.com with Google

This was never a secret. Being able to realise that fact we


TINIpushed
UMOH our
tiniumoh@gmail.com
customers to opt for better machines, but considering the list of frictions we
already had in on-boarding enterprises this just increased it more.
Continue as TINI

Slower Release Cycles


When you are starting up, you need speed. You need to release as quickly as
possible and there will also be a lots of production bugs
Signpopping up which
in to medium.com with Google

need to be solved even faster.


TINI UMOH
tiniumoh@gmail.com

But considering the fact that the smallest electron app we could come up
Continue as TINI
with is 100 MB and each bug fix was a release which auto updated by
downloading the same again on each users machine, it seriously slowed our
release cycle.

We ended up delaying release of bug fixes because users complained on


how many times they have to update our app. Plus in some organisations,
the end users didn’t have the permissions to install new apps. Which meant
they didn’t have permissions for updates too. This meant the IT guys in
organisations having to update in every users machine leaving them
frustrated.

Desktop Bias
When a windows user installs a desktop application, there is an underlying
bias present. They have gotten used to lightning fast interfaces powered by
simple .Net applications and locally hosted servers.
Presenting them with an electron app built with JS and HTML ( which is
significantly slower than the counterpart) created a mismatch in
Sign in to medium.com with Google

expectations.
TINI UMOH
tiniumoh@gmail.com

Performance Testing Continue as TINI

There isn’t much available for testing electron apps for performance. The
renderer process can be tested using standard frameworks and chrome
profiler. But if you wish to test the app with IPC messages and main process
memory consumption when interacting with a particular
Sign inscreen, you need
to medium.com with Google

to develop something custom.


TINI UMOH
tiniumoh@gmail.com

This sadly also meant debugging performance Continue as TINI

issues in electron to be a seriously tough task.

We have spent countless number of hours debugging performance issues


happening in the system, connecting to remote machines and trying to
analyse what exactly is eating this system up…..

Conclusion
Electron might be the way to go for you only if you have already achieved
product-market fit. There is a big benefit in having a computer screen open
up an the user seeing your app’s icon right there.

Please be aware of the potential problems of desktop


and specifically Electron apps pose.
Sign in to medium.com with Google

TINI UMOH
tiniumoh@gmail.com

Continue as TINI

No rights reserved by the author.

JavaScript Electron Tech Startup React

Learn more. Make Medium yours. Share your thinking.


Medium is an open platform where 170 Follow the writers, publications, and topics If you have a story to tell, knowledge to
million readers come to find insightful and that matter to you, and you’ll see them on share, or a perspective to offer — welcome
dynamic thinking. Here, expert and your homepage and in your inbox. Explore home. It’s easy and free to post your thinking
undiscovered voices alike dive into the heart on any topic. Write on Medium
of any topic and bring new ideas to the
surface. Learn more

About Help Legal


Sign in to medium.com with Google

TINI UMOH
tiniumoh@gmail.com

Continue as TINI

You might also like