fabiochiu/medium-articles huggingface dataset:
Case study: How Domino’s can improve their delivery experience
By: Elisey Kolev
Tags: Usability, UX, Case Study, User Interface, Food Delivery App

1. Is there a consistent internal visual design standard for all interface elements?

Issue 1: There is no internal visual standard for CTAs. Their position, size, text style, shape and background colour are incosistent.

The CTA position, size and style are incosistent

Issue 2: The product uses the visual style of default system elements (components, buttons, pop-ups, fields, map, fonts and more). The UI design doesn’t show the unique personality and style that the Domino’s brand is famous for.

2. Is there a consistent internal interaction design standard for all interface elements?

Issue 1: There is no internal interaction standard for CTAs. Buttons with the same style and expected behaviour interact differently — opening a new page, showing a pop-up or expanding additional input field. This adds uncertainty and makes it difficult for users to build behaviour habits within the product.

Issue 2: The buttons “Register” / “Log in” before login are in the same position and style as the “Choose a delivery method” options after log in. This is not a logical and consistent experience and might mislead users to think they are seeing the same “Register” / “Log in” buttons even after being logged in.

The position of login/signup and delivery options might mislead users

3. Is the product following established external UI conventions?

Issue 1: Most of the product CTAs are very small in size, making it difficult to tap on them. That results in frustration and might lead to reduced ease of use. For example, Apple says that CTAs in mobile UI should be at least 44Х44 pixels, while Microsoft recommends 34Х26 pixels.

Issue 2: Labels are placed inside the actual field entry, having them just disappear once the user starts typing. This interaction adds more cognitive load and puts too much on the user’s short term memory. Labels must offer guidance to users and aim to leave no room for interpretation in the entry fields. When it comes to the labels and placeholders in your app, they still need to abide by the general guidelines of form design: they need to be helpful, precise and objective.

The field entry labels disappear once the user starts typing

Issue 3: Combining the delivery details, shopping cart, recommendations, additional options and payment details in one mobile page leads to a long scroll, frustration and shopping cart abandonment. When they’re ready to buy, users shouldn’t be burdened with complicated and hard to understand lengthy checkouts. Instead, they need a laser-focused user experience that helps them do what they came to do. A progress indicator is especially important for visitors on-the-go who are looking to checkout quickly. A feature like this often makes the process less overwhelming as it can both identify how far long the customer is in the process as well as how much further they still need to go.
The expert usability review of FoodyLife app
By: Aleksandra Kulagina
Tags: Usability, Case Study, Mobile Apps, Food, Heuristics

If you’ve just launched FoodyLife app and want to note your breakfast, you can move the following way.

The first what you can see a friendly onboarding will be. The text under illustrations will tell you what the app is about, and these illustrations with smiles will make you smile. Although, if you are like me, you will just click on ‘next’ and won’t read the text above.

User experience has the name for this behavior. This is the paradox of the active user is a concept when the users are motivated to get started and to get their immediate task done.

After onboarding, the app asks to allow coach tips. And it isn’t the end, the app asks to choose a plan: personalize, standard male or standard female. And after it, we are introduced via text tooltips with the main functionality of the first screen.

Remind: my goal is to input and save my last meal.

I allow my intuition to guide me via screens. Tapping on ‘plus’ is associated with a meal adding, so I tap on it. In reply to it, the app offers to select how I would add a meal with or without a photo. I select ‘without a photo’, I don’t have a photo of my breakfast.

The following step is to record a meal. Notice, FoodyLife app has a manual entry, it increases the time of lead-in. Food groups adding is the final step and this step was the most complicated for me because I spent a lot of time to choose food groups.

Step 3

OK, we defined the object of the research. Now the analysis can be started, and first, the user flow should be divided into steps. And these steps are onboarding, selecting of adding a meal and describing a meal.
Deploy both ends of the MERN App to the same Heroku app
By: Sumit Kolpekwar
Tags: Deployment, Full Stack, React, Heroku, Node

Setting up frontend

I used Create React App and set the PORT to 3001 for development because the backend would be running on the PORT 3000.

Setting up Backend

Backend has one script for production and one script for development.

make sure your express has these few pieces of code

the above code makes sure that your server uses the port given by Heroku or port 3000 during development.

To ensure that your app uses the frontend build created by CRA during production and redirects to the index if a path doesn’t exist.

Renaming API Routes

Heroku only gives one port for both the ends. So if you have clashing routes like ‘/users’ or ‘/about’ in both React and API endpoints in your express app, you will get errors.

You might be able to navigate to different routes such as yourapp.com/about because of how react is build, but when you refresh your page you would get an error

Cannot GET /about

A simple way to solve this is to rename your API endpoints ( for example )

Refactoring URLs for React

By default when fetching data through Axios in React from the backend, without specifying any URL it always sets the port to the current port, for us that would be 3001 (in development ). This default behavior works on production as both ends would be on the same port.

But during development, we need to make sure it fetches data from port 3000 and not 3001.

This assigns URL based on if the app is deployed on Heroku or is running on the localhost for development.

Root Package.json

Running both frontend and backend is annoying because I have to change directories and start the server EVERY TIME.

So I wrote scripts to manage it from the root without changing the directory.

Create a package.json file in the root directory, and add these scripts

Now you can run both frontend and backend (in different terminals) in development mode by running

npm run frontend and npm run backend

Deploying to Heroku

Heroku runs the start script on the build which installs and runs our backend, after that, it runs the heroku-postbuild script which installs and builds the react app for a production build.
Connecting to MySQL in NodeJS
By: Sayantan Mukherjee
Tags: JavaScript, Database, MySQL, Nodejs, Node

How to connect your MySQL database to your NodeJS application? It’s very simple. Don’t believe me? Here’s how you can do it.

First, create a folder in your Node application direction named config. Now, this can be of any name of your preference.

Inside this folder, create a file named database.js. This file will contain our database configuration and connection.

Now, there are 2 ways in which you can create a database connection in NodeJS. The simple connection and a pool connection. I prefer the latter because of a few reasons which I am going to explain later.

Creating a simple connection to MySQL database using NodeJS

Open the file database.js

Simple connection

Let’s discuss a bit about what we did in the above code.

First, we need to require a module named mysql. To install it, simply use

npm install mysql

Now, we need to create our database configuration.

For this, we are going to use createConnection function of mysql module.

We are going to pass an object as function parameter. The object will contain the host, i.e. basically your database IP or domain name or localhost if we are trying to connect to our local database. Now, the user and password will be the username and password of your database which is used to log into your MySQL database. The database will be the name of the database we want to access. and Port by default is 3306 for MySQL.

To connect to our database, we are going to use the connect method which on success will create a connection to our database.

This was a simple database connection. Now, this type of connection is fine when we are not dealing with multiple connections at the same time. For heavier workloads, we use connection pooling.

We can use pooling directly to handle multiple connections and reuse the connection. This helps us handle multiple requests to our server at the same time without causing any delay.

For connection pooling, we are going to use the following code snippet.

Pool connection

Now for pool connection, we use more or less the same configuration as used in a simple connection above. We only use a connectionLimit, i.e. number of connections that are allowed at a time.

Also, instead of createConnection function, we use createPool function.

This is how we connect our MySQL database to our NodeJS application.

I hope this helps you to understand which connection to use in your application and help you connect to your MySQL database.
How I deployed my website from my phone
By: Adrienne Kerr
Tags: Reactjs, Nodejs, Web Development, React, Node

Two weeks ago, I was waiting for my flight to Rio for Carnaval. There was one thing I’d forgotten to do before leaving and that was to update my website. For fun, I’d added the react-snow-effect NPM package that I’d written years ago which makes it looks like it’s snowing all over your website.

This didn’t reflect the weather in Seattle at the time and definitely did not match the sunny weather I was about to be experiencing in Brazil.

Fortunately, I’d already pushed all the code up to github and my co-worker had recently reminded me about a freemium tool called netlify. This tool allows you to deploy your website by simply pushing commits to your github repository.

I signed up with github, authorized netlify, and installed it on all of my repositories. Now all of my github projects are live. For example my quintus-cats repo is now live at www.quintus-cats.netlify.com.

Not only does netlify hook up to my code, it’s able to compile my code for me. My personal site is a react app and netlify is able to install all the dependencies and compile all the .jsx code making it super easy for me to makes changes, even from my phone!

Have you experimented with netlify yet? Let me know in the comments!
Verge Currency + GetBlock
By: Nichola Wilkinson
Tags: Getblock, Xvg, Crypto, Verge, Node

Verge Currency & GetBlock are happy to announce a collaboration providing access to XVG nodes. GetBlock is a Blockchain-as-a-Service (BaaS) platform that provides a fast and easy API connection to full nodes.

GetBlock provides a connection to blockchain nodes for the most popular cryptocurrencies with JSON-RPC, REST, and WebSockets. You can immediately connect your app to a blockchain, as GetBlock relieves you from running a node yourself.

Verge Currency is a secure and user-friendly digital currency designed for everyday use. Verge promotes ease-of-use, speed and community ownership. With Verge, businesses and individuals have flexible options for sending and receiving payments securely and efficiently all around the world in a matter of seconds.

Verge Currency node is now live on GetBlock, with their non-stop working servers located in Germany, where a connection can be established at all hours at a speed of 1 GB/s. Each node can be integrated using various API methods, while the method available for XVG is JSON-RPC.

GetBlock’s pricing system is structured in a way that the purchased requests do not have an expiration date and can you spend 40,000 requests/day for free!

To find out more head over to Twitter @getblockio or Telegram
Latest dev news
Tags: Development, Metahash, Cryptocurrency, Mhc, Node

Friends, all recent weeks the #MetaHash team has been working hard to correct the Cores synchronization error. We will deal with this problem in the nearest future.

The recent incident with block generation has shown why it is important to correct inaccuracies in Cores code before they are fully released, rewarded, and decentralized. After all, in the future network inactivity is unacceptable even for a few minutes.

Meanwhile, there is a solution to such a problem. The TraceChain protocol has a unique ability to self-recover. This feature will reduce the time for troubleshooting (more details can be found on page 10 of the YellowPaper). Of course, it should be further developed, but the groundwork is already done!

Now, the work on Сores does not stop for a day. But before the new version of the main role is published, we have to debug the interaction between Torrents and Cores. That’s why we have asked users to suspend Cores testing for a while, to avoid wasting resources.

Soon, when the updated code will be published, we will announce the last step of testing aimed to introduce awards and, eventually, decentralization.

Stay tuned!

— — — — — — — — — — — — — — — — — — — — — — — — — —

Our website

#MetaGate

Telegram

Twitter

Reddit
How to add and remove nodes in Apache Pulsar
Tags: Apache Pulsar, Big Data, Node, Tech Blog, Distributed Systems

Adding and removing nodes is one of the most common operations when managing a distributed system. We’ve heard from users that have used both Apache Kafka and Apache Pulsar that adding and removing nodes can be operationally burdensome in Kafka because it requires operations teams to manually balance data between nodes in the cluster. This balancing act is known to be error prone and to consume a lot of bandwidth, making it all too easy to break production deployments.

Apache Pulsar, in contrast, is built on top of a layered, segment-oriented architecture that separates stateless serving from stateful persistence. This clean separation between concerns allows for independent scalability between the serving and persistence layers, which significantly simplifies operations. In Pulsar, adding and removing nodes is incredibly simple because there’s no need to rebalance data.

For some technical details behind node operations in Pulsar, check out our blog post How a segment-based architecture delivers better performance, scalability and resilience.

In this more practical tutorial video, I’ll show you how easy it is to add/remove nodes to/from an existing Apache Pulsar cluster.

Video source:https://youtu.be/_BW67HAkS-w

More on Apache Pulsar

If you want to learn more about Apache Pulsar, please visit the official website at https://pulsar.apache.org.

If you want to learn more about the differences between Apache Pulsar and Apache Kafka, please checkout our comparison series of blog posts:

You can also participate in the Pulsar community via:

The Pulsar slack channel. You can self-register at https://apache-pulsar.herokuapp.com.

The Pulsar mailing list.

For getting the latest updates about Pulsar, you can follow the projects on Twitter @apache_pulsar.

About the author

Sijie Guo is the founder of StreamNative, VP of Apache BookKeeper, and PMC Member of Apache Pulsar. Previously, he was the tech lead for the messaging group at Twitter, where he co-created Apache DistributedLog. Prior to Twitter, he worked on push notification infrastructure at Yahoo. You can follow him on twitter.
> Create a simple app with Mix tool
By: Kasun Edward
Tags: Software Development, Computer Science, Elixir, Functional Programming, Erlang

Setting up Elixir Environment

All the details necessary to install Elixir in your OS are listed in this installation page. After installing you can check the current version of the Elixir by executing iex -v

$ iex -v

IEx 1.9.0 (compiled with Erlang/OTP 20)

Creating Elixir project & add dependencies

in order create a new Elixir project, we use Mix, a build tool comes with Elixir which provides methods for creating, running, testing Elixir applications and managing dependencies.

To create a new project, we can use mix new command .

$ mix new ex1

* creating README.md

* creating .formatter.exs

* creating .gitignore

* creating mix.exs

* creating lib

* creating lib/ex1.ex

* creating test

* creating test/test_helper.exs

* creating test/ex1_test.exs Your Mix project was created successfully.

You can use “mix” to compile it, test it, and more: cd ex1

mix test Run “mix help” for more commands.

A file called mix.exs has been created inside the project directory. It’s main function is to configure the project. Also mix generates a default file called lib/ex1.ex . It comes up with a module which has a default function called hello

Compiling the application

To compile the project you can execute,

$ cd ex1

$ mix compile

After a successful compilation, it will give following output.

Compiling 1 file (.ex)

Generated ex1 app

Once project is compiled , _build directory is created inside project root folder. It contains all the articafts generated by compilation such as ebin folder etc.

Using the interactive shell

$ iex -S mix

This will starts an interactive iex session as follows.

Interactive Elixir (1.9.0) - press Ctrl+C to exit (type h() ENTER for help)

iex(1)>

By executing above command, both application and dependencies will be loaded to current run-time. In this session you can call your module functions as follows.

iex(1)> Ex1.hello()

:world

Mix provides a command called recompile , which is used to load new changes while you are in the iex session.

Let’s make small change to hello() function and recompile it.After executing the recompile command it will give following output when there is a change in the code.

iex> recompile()

Compiling 1 file (.ex)

:ok

Following output will be generated when there is no change.

iex> recompile()

:noop

Managing dependencies

Since the application we just created is a basic one, it has no any dependencies. But a large application may contain hundreds of dependencies.

Mix comes with a cool way to manage dependencies. Required dependencies of the application are listed in the deps function in mix.exs file. For example let’ add ecto_sql and myxql libraries to our project as follows.

defp deps do

[

{:ecto_sql, "~> 3.0"},

{:myxql, "~> 0.2.0"},

]

end

To fetch the dependencies , you can execute following command inside the root directory of the project.
Manage config variables in an elixir project
By: Julien Corb
Tags: Config, Elixirlang, Programming, Elixir

free of rights image from pexels.com

Following this very interesting conversation, the elixir core team decided to remove the generation of the config folder when creating new project using mix new . In short, here is why, according to José Valim :

mix new is mostly used for libraries and libraries should be actively discouraged from defining (because it is global) or using entries (as it only applies to the library) in config

If you fell on this post with the aim of coding a library, you should thoroughly read the library guidelines. If you are working on something else, like a personal project, the following might be useful :).

Doing it the right way

Start by creating a config folder at the root level of your project. Inside this folder, create a config.exs file.

If you have already created mix projects before april 2019, what you just did might seem familiar to you. mix new use to generate this config/config.exs file for us. So far, nothing has changed.

At this point, you might be tempted to use the Mix.Config module to populate your config file, as it use to be the case in your older projects. However, Mix.Config is now deprecated and you should from now use the Config module. The Config module is used as a replacement for Mix.Config as of elixir v1.9. and is not Mix-specific.

You can now write in your config.exs file :

import Config config :some_app,

key1: “value1”,

key2: “value2” import_config “#{Mix.env()}.exs”

Replace some_app with the name of your application and write each key/value pair of your config variables underneath.

Now notice that import_config “#{Mix.env()}.exs” is optional : you only need this line if you create several config files in order to use different configurations depending on your environment : config/dev.exs , config/test.exs … Creating those files follows the same pattern as explained above for the config/config.exs file.

Your config variable are set ! You can now retrieve them anywhere in your code by using Application.fetch_env!/2 `:

“value1” = Application.fetch_env!(:some_app, :key1)

For instance, I am currently working on a small project in which I use the great Pexels API to find nice landscape images. Here is what my config/config.exs looks like :

import Config

pexels_api_key: “1234567890AZERTYUIOP”,

pexels_url: “ config :landscape,pexels_api_key: “1234567890AZERTYUIOP”,pexels_url: “ https://api.pexels.com

I then fetch them as module attributes like this in lib/landscape/pexels.exs :

defmodule Landscape.Pexels do

@pexels_url Application.fetch_env!(:landscape, :pexels_url)

@pexels_api_key Application.fetch_env!(:landscape, :pexels_api_key) # bunch of functions here... end

A word on migration

Again, if you were using config files to configure your library in the past, I highly recommend you to have a look here and update your lib. If you still need to use config files, you can find the steps needed to migrate your project from Mix.Config to the Config module here.

That’s it ! Hope this will be helpful in your elixir journey :)
Delete from join table with Elixir Ecto.Query
By: Hisa Ishibashi
Tags: Ecto, Database, Kubectl, Elixir

Photo by Tim Johnson on Unsplash

Recently, I had to access the remote console of an Elixir/Phoenix application running in production, to manually delete a record from the database because the feature to delete those records was not implemented yet.

CAUTION: make sure to backup your database before performing destructive operations, or avoid them at all if possible to prevent data losing or failing to comply with data policies applied to your business.

The application was released with Distillery, is running inside a Kubernetes Pod, and given that I had all the credentials and configuration to access it via kubectl , then I executed the following command:

$ kubectl exec --namespace=myapp-prod -it $POD_NAME bin/myapp remote_console

If the app was deployed with Mix Releases instead of Distillery, then I think the last command would’ve been just remote instead of remote_console .

Once inside the console, my 1st attempt resulted in a foreign_key_violation because I forgot to put on_delete: :delete_all in the migration of the table dependent on the record, the join table.

iex(myapp@127.0.0.1)4> Repo.delete(Task, 123) ** (Postgrex.Error) ERROR 23503 (foreign_key_violation) update or delete on table “tasks” violates foreign key constraint “people_tasks_task_id_fkey” on table “people_tasks” table: people_tasks constraint: people_tasks_task_id_fkey Key (id)=(123) is still referenced from table “people_tasks”. (ecto_sql) lib/ecto/adapters/sql.ex:605: Ecto.Adapters.SQL.raise_sql_call_error/1

(ecto_sql) lib/ecto/adapters/sql.ex:538: Ecto.Adapters.SQL.execute/5
How To Upload Files In Elixir Phoenix JSON Api — Tentamen Software Testing Blog
By: Karlo Smid
Tags: Phoenix Framework, Elixir

Gigalixir Node Memory Consumption Of 25MB File Upload As Base64 encoded string.

TL;DR

In my Elixir Phoenix application, I have a JSON API for mobile applications. One endpoint accepts file uploads. In this post, I explain my architectural decision why to implement file upload as multi-part form data.

JSON API Upload As Base64 Data Stream

Google returned this excellent DockYard blog post: Building An Image Upload API With Phoenix. I implemented image and video upload as a Base64 encoded string in JSON. The above Screenshot depicts memory consumption for file upload of 25MB. So for 40 concurrent file uploads of that size, I will need 1GB Gigalixir instance. What about 400 concurrent uploads?

MultiPart Form Data

I switched to multipart form data. Your controller is straightforward:

@spec add_note(Plug.Conn.t(), any) :: Plug.Conn.t()

def add_note(conn, params) do

When clients send multi-part Form Data with a file, the Phoenix framework does all the heavy work before your controller is in control. So if you sent a file under the form data attribute named screenshot , then Phoenix will put in params["screenshot"] Plug.Upload structure.

Note that you still can send back a JSON response. My initial guess was that I must use JSON on input for JSON API. Wrong, we can also use multipart form data. For sending additional attributes, just send them as additional form data parameters.

The Gain

The same file upload of 25MB left the following memory footprint on my Gigalixir instance:

Memory Consumption For Multipart upload Of 25MB file

Check two mini spikes at the end. 3MB memory consumption.

Under The Hood

Plug.Upload is A server (a GenServer specifically) that manages uploaded files. Uploaded files are stored in a temporary directory and removed from that directory after the requested file dies. This temporary location is stored in :path an attribute. But the most important is this:

All options supported by Plug.Conn.read_body/2 are also supported here. They are repeated here for convenience: :length — sets the maximum number of bytes to read from the request, defaults to 8_000_000 bytes :read_length — sets the amount of bytes to read at one time from the underlying socket to fill the chunk, defaults to 1_000_000 bytes

Socket stream is read in 1Mb and is written to tmp file location using Elixir File.Stream. When 1Mbytes is ready, they are written to file. Making memory impact minimal.

Remember
Elixir’s with statement is fantastic
By: Alex Loukissas
Tags: Functional Programming, Software Development, Software Engineering, Elixir

Elixir’s with statement is fantastic

I gotta be honest. It was not exactly love at first sight when I first encountered Elixir’s with statement. But just like I learned to appreciate (and love) the whole non-defensive/let-it-crash approach, the same happened here as well.

The result: I was able to rewrite a bunch of complicated functions with very hard-to-read nested case and/or cond statements in a very clean, and, more importantly, maintainable and extensible way using with .

Basic usage

The basic premise of with is that it lets you chain together pattern matches and arriving at the positive result, in a very concise statement. Error handling (if any — remember, this is still let-it-crash land) is done in an optional else clause, after we’re done with the positive codepath.

Let’s look at a basic example. Suppose you’re working with the Elixir library for Stripe and you want to implement a function that creates a new subscription for a customer. Here’s what this may have looked if we hadn’t used the with statement:

Function implementation using nested case statements

What’s wrong with the code above? Here’s a hint:

Spaghetti: better eaten than debugged. Photo by Mae Mu on Unsplash.

Let’s try to write the same function using the with statement:

Function implementation using with statement, without nested case statements

That’s a lot cleaner and easier to read, no?

Alas, it’s not all rosy

But there’s a problem. In the second implementation, it’s really hard to infer which of the steps of the function calls failed the pattern matching, so that we can return a more useful error to the caller. It also makes it harder to debug.

So, did we trade readability for usability?

We can do better!

Fear not, reader! A really simple solution that we’ve been leveraging heavily in our codebase in AgentRisk is to leverage pattern matching. Here’s how:

Each chained function call returns a tuple with an atom that helps us know exactly where things went wrong in the chain.

If we rewrite the previous code example like this, this is what we get:

Function implementation using with statement, with improved error handling

In the example above we are swallowing the error return values, but this was in favor of simplicity. The core idea here is that we tag each step with a unique tuple pattern, so that we can know exactly where the error occurred.

A final note

Hopefully, this post clarified a few of the nuances of Elixir’s with statement. We have not found a better way to implement complex functions in our codebase, for readability, maintainability, and ease of debugging.

I want to thank Carlos Brito Lage for introducing me to this pattern as well as editing an early version of this post.
Custom ExUnit Assertion
By: Tyler Pachal
Tags: Macro, Metaprogramming, Exunit, Elixir

Writing an assert_invalid macro for ExUnit assertions. Implementation at the bottom.

I was working a lot with Ecto Changesets - using them for validation in my HTTP application. The application code (the code in my lib/ folder) was very nice, but I was not happy with the verbosity of the tests. Each test looked something like this:

An example without my custom assertion

This was okay for a single test about a single field, but quickly lead to a tonne of copy-and-paste across multiple tests that were asserting on multiple fields.

The solution was to create a custom assertion that could combine and abstract the multiple assertions away.

Here is an example test suite which uses assert_invalid (my creation) and shows off the error messages when the assertions fail — I think having good ExUnit error messages is the most important part!

Example Ecto.Changeset tests using assert_invalid that show off all of the various assertion error cases

Here is the resulting output:

Example output displaying the error messages you would see when your assertion fails

Most importantly, here is the code:

The implementation of assert_invalid

It is necessary for the assertion to be a macro for two reasons:

We need access to the flunk/1 and assert/1 functions that are provided by ExUnit when we run the tests We would like to expose the error_message value so that users can write expressions against it

The most interesting part of the code is the call to Kernel.var!/2 on line 15. By default, variables declared inside of a macro are hygienic and will not impact variables defined where the macro is expanded. Using Kernel.var!/2 is one way to explicitly disable that hygiene and have the error_message value be available in our tests.

Additionally, using the IO.ANSI module to color my stdout really helped make the assertion errors more readable:

Example IO.ANSI coloring

I am not a metaprogramming expert, but hopefully this example code will be useful for other folks getting started with writing their own assertions.
Refactor Code By Using the Ternary Operator in JavaScript
By: Tran Son Hoang
Tags: JavaScript, ES6, Engineering, Programming, Front End Development

Ternary operator vs “if” statements in real life

When I was in my first year in software development, my first mentor preferred to write long but readable code. He believed that if ... else ... is more readable than condition ? true case : false case .

So I put it in my mind to never use the ternary operator because it is too complex. Something like:

ternary operator like a hell

However, a few years later, I got in trouble in code reviews in my next company about if ... else ... statements. My co-worker preferred to use ternary operators to shorten the code. He believed shorter code made it more clean and simple.

I’ve read clean code, and I think that simple code is always better. But it’s easier said than done. I blamed it on the feature for being complicated, not my if statements.

I have no problem with a simple ternary operator like:

simple ternary operator example

But, for complicated cases like the hell above, I do not know how to handle it. My co-worker asked me to try to shorten my code and reduce the number of if statements.
Linked list Javascript實作及Leet code題目解析
Tags: JavaScript, ES6, Singly Linked List, Leetcode, Linked Lists

開始之前

因最近正在複習資料結構(基本上就是重新學習了吧😂)，希望能把一些比較重要的部分記錄下來，並在撰寫文章的過程中讓自己的記憶更加深刻。以下會盡量使用 ES6 的語法來創建資料結構的實例，當然也會有思慮不周的部分，還請大家多多留言指教！

Intro

Linked list 鏈結串列，是一種動態的資料結構，相對於 Array 陣列，不需連續的記憶體空間即可儲存，對於資料的操作成本較低；然而若欲取得其中某一節點 Node 上的資料，則必須從頭開始遍歷查找。

A simple example of a linked list, nchuuu

Practice

由上圖可知，一個串列中存在多個 Node 結構，且 HEAD 會指向第一筆資料；而 Node 結構中由 Item 存儲資料，Next 負責指向下一筆 Node。故我們創建一個 Linked list 的 Class 思路為：

鏈結串列有起始位置 head ，亦即串列中第一筆 Node。 Node 節點以 item 存放資料。 Node 節點以 next 作為指標，指向下一個 Node。 為 List 加入一些參數如 length ，便於後續操作。

節由以上整理我們可以先開始創建符合需求的 ES6 Class：

LinkedList及Node分別為兩個Class，使用上較為簡便不會混淆。

有了 Class 後必須有對應的方法來操作資料(ex: Array.push() )，以下會依序實作(1)新增，(2)刪除，(3)插入。

(1) 新增 (append)

新增資料通常我們會串連至 Linked list 的尾部，也就是 append 一個節點。若為串列的第一筆資料，將串列的 head 指向新增的 Node 即可；其它則需透過遍歷找到尾部的 Node 再加入。故我們可以在 Linked list 中新增一個 method append ：

首先判斷是否為第一筆資料，將串列的 head 指向新增的 Node ；若否則利用 while loop 判斷遍歷的節點找到最後一個 Node (也就是上例的tail)，再將其上的 next 欄位指向新的資料。另外也別忘記將 List 的長度往上加一( this.length++ )。

(2) 指定位置移除(removeAt)

給定一個 index 移除資料，如同新增的步驟，先判斷移除的項目是否為第一筆，若是，則將 head 指向第二筆資料；若否，則遍歷找到該 index 下的 Node ，移除的操作即是將前一個節點之 next 欄位指向下一個節點。

removeAt 的 method 如上例，需注意的是 current 及 prev 兩個變數的使用；透過他們我們可以對遍歷到的節點進行暫存，到達指定 index 時將 next 的指向置換即可。操作的結果如下：

// a new linked list

let ln = new LinkedList(); // append items

ln.append('1');

ln.append("2");

ln.append("3"); // remove item in index 1

ln.removeAt(1); // out print of ln

{

"length":2,

"head": {

"item":"1",

"next":{

"item":"3",

"next":null

}

}

}

(3) 指定位置插入(insert)

插入的操作同樣和刪除很像，除了判斷是否為第一筆外，透過遍歷找到我們給定的 index 位置，並利用 prev current 等變數輔助，改變 next 指向就好囉。

Leet code

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

在 Leet code (2) Add Two Numbers 中，題目給予兩個不為空的串列，分別代表兩個非負整數，其數字的“位數”是反向儲存的 (2→ 4→ 3, 代表342)。最後將兩個串列中數值相加後，以同樣的型式回傳這個串列(其實這個reverse order個人覺得挺陷阱的😂，畢竟我們在處理時只要按照同樣的順序處理，也不太需要擔心👍)。

Example: Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)

Output: 7 -> 0 -> 8

Explanation: 342 + 465 = 807.

這邊解題的思路為：
Implementing a Queue in JavaScript
By: Javascript Jeep
Tags: JavaScript, ES6, Queue, Programming, Data Structures

Implementing a Queue in JavaScript

Image by Levi Jones on UnSplash

A queue is a list — similar to the real world queue. The one who gets into the queue first is the one who is removed first from the queue.

Technically speaking, this process is called first in, first out (FIFO). The element which is inserted first will be removed first from the list

Elements are always added to the end of the list and removed from the front of the list.

Different operations in Queue are:

Enqueue → Add an element to the queue

→ Add an element to the queue Dequeue → Remove an element from the queue

Operations we are going to implement:

Inserting an element at the end of the queue

Deleting an element in the front from the queue

Get the front element

Get the Last element

Check if a queue is empty

Print the elements of the queue

Print the length of the queue

Let’s create a Queue class.

class Queue {



constructor(){



this.data = [];

this.rear = 0;

this.size = 10; } }

data → is the list in which we store our elements

rear → is used to store the position in which the next element will be stored
JavaScript journey: from Zero to Hero
By: Divyanshu Semwal
Tags: JavaScript, ES6, Angular, Nodejs, React

Initially, many developers felt that JavaScript is an inferior language because of its simplicity. In fact many developers didn’t assume JavaScript as a programming language. JavaScript was only scripting language for them.

But after coming ES5 at 2009 and Node.js at 2010, JavaScript started to become very popular among developers. After introducing AJAX (Asynchronous JavaScript And XML) in JS, it became clear that JS allows developers to build powerful and highly responsive web applications.

Foremost I would like to thank “ Brendan Eich” who introduced JavaScript in 1995 during his running project of “ NetScape 2 “. NetScape was leading browser of that time which was competing with Internet Explorer of Microsoft.

Eich prepared JavaScript in 10 days to bring back NetScape into playground. Initially it was named as LiveScript but later it was renamed as JavaScript under marketing strategy to leverage Java.

ECMA which stands for European Computers Manufacturers Association standardized JavaScript with standard name of ECMA-262. JavaScript was continuous improved and still developing by Firefox.

Advantages:-

Speed :- JavaScript is interpreted language. It means there is no need to compile JS codes into machine code. So, it reduces compilation time. Simplicity :- Easy syntax makes this language easy to learn & understand, feasible to implement. This is the actual beauty of this language. Popularity:- Many popular companies like Google, Amazon, FlipKart use JS in front end. Now PayPal which is another popular company uses JS in back end also. According to PayPal:-

“By using Node.js in backend, it is built twice as fast with fewer people, reduced 33% line of code, reduced 40% files, can handle 2x request/second and has 35% faster response time.” Server Load :- It operates client side, so data-validation is possible on browser. So there is less need of communication with server to perform many tasks. Versatility:- This is another beauty of JS. JavaScript can play on both side. After introducing Node.js, JavaScript can work perfectly in back end also.

1. https://youtu.be/aX3ZABCdC38

2. https://youtu.be/1EyRscXrehw
JavaScript ES6 Refreshment
By: Ashwani Garg
Tags: JavaScript, ES6, Es6 Js, Javascript Es6, Javascript Tips

CONST & LET

You can not reassign const, but if you want, you can use ‘let’ keyword for reassignment.

// example of let

let name = 'Ramu';

name = 'Shamu';

console.log(name);

// output

Shamu // example of const

const name = 'Ramu';

name = 'Shamu';

console.log(name);

// output

error: Assignment to constant variable

Note:- Same applies to objects & arrays too, if you using const to create an object, you can not reassign that object again. Although you can change the values of the parameters inside the object.

Arrow Functions =>

// Old way to write JS functions

function sayHello(name){

console.log('Hello '+name);

}

sayHello('Ashwani') //output

Hello Ashwani /**

* @param {*} name

* ES6 way

*/ const sayHi = (name) => console.log('Hi '+ name); // or without braces, if passing single parameter const sayHi2 = name => console.log('Hi '+ name); // or using Template literals const sayHi3 = name => console.log(`Hi ${name}`); sayHi('World')

sayHi2('ES6')

sayHi3('JS') //output

Hi World

Hi ES6

Hi JS

let’s make a dummy array

const cars = ['Hyundai', 'Tata', 'Toyota'];

forEach — iterates the function on each element of the array.

cars.forEach((car, index)=> console.log(index, car)) //output

0 Hyundai

1 Tata

2 Toyota

map — pretty much same as forEach, but returns the data in a single variable.

const fruits = ['Apples', 'Bananas', 'Grapes'];

const fruit = fruits.map(fruit => fruit.slice(0,-1).toUpperCase());

console.log(fruit);

filter — filter the data, checks the condition on each element of the array

const people = [

{id: 1, age: 20},

{id: 2, age: 30},

{id: 3, age: 40},

{id: 4, age: 50},

] // lets filter the people with age less than 41 const filtered_data = people.filter(person => person.age < 41 );

console.log(filtered_data); // output is a new array with filtered data

[

{ id: 1, age: 20 },

{ id: 2, age: 30 },

{ id: 3, age: 40 }

]

Spread Operator …

— just takes the copy of the given array and can insert more elements at the end of the array.

const arr = [1,2,3];

const arr2 = [...arr, 4, 5];

console.log(arr2); //output is

[ 1, 2, 3, 4, 5 ]

DeStructuring

— this means you can take the values of an object in a variable, and directly use that variable, let’s say you have a vue or react component.
JavaScript ES6 Promise: callback hell的救星
By: Brian Wu
Tags: JavaScript, ES6, Programming, Promises, Web Development

如何使用 Promise？

建構 Promise

在說明如何使用 Promise 之前，我們先來看看如何使用 Promise() 建構子來建構一個 Promise：

首先，Promise 建構子有一個參數，此參數需要傳入一個函式，而此函式有兩個參數，兩者亦需分別傳入一個函式。其中，第一個函式一般被命名為 resolve，其可接受傳入一個參數，當 resolve 被調用，則此 Promise 之狀態 [[PromiseState]] 會解析為被履行 (fulfilled)，而且當初傳入 resolve 之參數，會成為該 Promise 的值，此值會存於 [[PromiseResult]] 屬性；第二個函式一般被命名為 reject，其也可接受傳入一個參數，當 reject 被調用，則此 Promise 之狀態 [[PromiseState]] 會解析為被拒絕 (rejected)，且當初傳入 resolve 之參數，亦會成為該 Promise 的值並存於 [[PromiseResult]] 屬性。我們可以在傳入 Promise 建構子的函式中，決定該在甚麼時候調用 resolve 或 reject。而 Promise 的值，則會成為後續 then 以及 catch 方法的回呼函式被調用時的引數。

我們用下面的程式碼來進一步說明：

在上例中，我創建了一個通過考試的 Promise，可以想像成我「承諾」會通過考試。如果分數大於 60 分，就調用 resolve 來履行承諾，並傳入通過考試的訊息作為 Promise 的值；如果分數沒有大於 60 分，就調用 reject 來拒絕承諾，並傳入沒通過考試的訊息作為 Promise 的值。

使用 Promise

接著，我們就來使用剛剛創建好的 Promise。前面提到，then 方法接受兩個回呼函式作為參數，第一個函式會在 Promise 被履行時調用，第二個函式會在 Promise 被拒絕時調用，其中第二個函式是選擇性的。此處，我們只傳入第一個函式來處理 Promise 被履行時要做的事。而 catch 方法則接受一個回呼函式作為參數，其會在 Promise 被拒絕時調用。而不論是傳入 then 或者 catch 的回呼函式，其被調用時，都會使用 Promise 的值 [[PromiseResult]] 作為引數傳遞給參數 msg。

因此，以上程式碼的執行結果有以下兩種：

Congrats! You have passed the exam!

// or

Oh no! You failed the exam...

說到這邊，你可能並不覺得 Promise 相較於 callback 有甚麼優點，而只是又學了一項複雜難懂的工具。不過，Promise 還有一個相當實用的寫法──「Promise chaining」。當有許多非同步事件需要依序處理時，chaining 提供了我們優雅易讀的寫法，讓我們繼續看下去。

Promise chaining

前面提到 Promise 有 then 與 catch 兩個實例方法，此兩方法在調用後會回傳一個新的 Promise，而此新 Promise 的值 [[PromiseResult]] 會是 then (or catch) 之回呼函式之回傳值。由於新的 Promise 亦可以調用實例方法 then，因此，我們可以將想要依序進行的非同步操作寫成 Promise，並將它們串連 (chaining) 起來。讓我們看看下面的例子：

執行結果如下：

AsyncOp-1 is completed!

AsyncOp-2 is completed!

AsyncOp-3 is completed!

This is the end of Promise chaining.

接著，我們來看看這幾行訊息是怎麼被印出來的。首先，當第一個非同步操作 asyncOperation1() 回傳之 Promise 被 fulfilled 後，將其值 'AsyncOp-1 is completed!' 這段字串傳遞給第一個 then 內部回呼函式之參數 msg，並調用它，因此打印出上方執行結果的第一行訊息。接著，第一個 then 方法回傳 asyncOperation2() ，此函式再回傳第二個 Promise，此 Promise 被 fulfilled 後，再將其值 'AsyncOp-2 is completed!' 傳遞給第二個 then 內部回呼函式之參數 msg，並予以調用，打印出第二行訊息……。因此，就有以上的執行結果。

至此，在對 Promise 之狀態、方法與串連有初步了解的狀態下，我們已經擁有解決上篇文末 callback hell 的能力了。
How I Keep my Long-Distance Marriage Healthy
By: Jennie Silva
Tags: Long Distance, Couples, Relationships, Marriage, Love

Photo by Jasmine Wallace Carter from Pexels

My husband is an over-the-road truck driver which means he travels pretty much every time he leaves home for work. Now, when I say he travels, I mean far. Really far. He’s currently on his way to Edmonton, Canada- it’s not the first time he’s done this and it definitely won’t be the last. When he leaves, he not only has to leave me behind but also our 6-month-old baby girl. The sacrifices he makes to keep our family sustained is an endless list, which is what makes it so EASY to love him, even more, every single day.

My husband is gone about 10–15 days out of each month, and when business is really good he can be gone even longer. He hauls hazardous chemicals all around the United States and up into Canada as well. When he’s dispatched [assigned a new load] he usually wakes up around 4 to 5 in the morning and is out of the house within the hour. We get a quick kiss and hug goodbye and then he’s out the door. I always tell him, “Come back home to me” and he always replies that “of course [he] will.” This has been our ritual for the last 3 years, and it’ll continue to be until we are blessed to have him home full time.

Being a truck driver means staying away from your home, family, and friends 80% of the time. I still can’t begin to imagine how my husband feels when he’s over 2,000 miles away from home…but I know exactly what the separation of 2,000 miles feels like. I’ve had numerous friends and family members wonder aloud, “How does she do it?” and I’m often told, “I could NEVER do that” once they hear how long he’s been gone. Plus having to take care of our daughter? “No way!” they always say. Yes, I’m still married to him. Yes, it’s hard. Yes, I get lonely. But, I know our marriage is stronger than ever and I know our baby girl still feels his presence around her even in his absence.

I’m asked all the time how we manage to stay so connected to each other when he’s out on the road and how we keep our relationship strong. I know I can’t be the only trucker’s wife out there, or the only person with a significant other [SO] whose job keeps them away from home for days at a time, so I’m hoping this article really helps anyone who is struggling to find the glue to keep their relationship together.

So, without further delay, here are my tried and true tips to keep a long-distance relationship strong and healthy.
In a Good Relationship, It’s the Third Person That Matters
By: Brian Byrne
Tags: Grammar, Retrouvailles, Couples, Relationships

In a Good Relationship, It’s the Third Person That Matters

Nope, this is not an article on polyamorous relationships. I’m not qualified to even approach that one. Would not know where to start. Although what I’m going to talk about applies to all relationship types.

Six years ago, my wife and I started presenting for Retrouvaille, a program for troubled marriages. We are not qualified counselors. The primary qualification is going through a Retrouvaille program and coming out the other side still married.

Apart from the more structured presenting, we informally talk to a lot of couples. We don’t try to address their problems, but we do listen for parallels to our own issues and talk about what we did to either get past them or what we do to keep working on our relationship challenges today.

After one long conversation that lasted close to an hour, the other couple went back to their room and I turned to my wife and said, ‘What was that woman’s name?’ Neither of us knew. We had to look in the registration list to figure it out. A person in a supposedly committed relationship had referred to his spouse over a dozen times and never mentioned her name.

It seemed like a small thing, but I started to pay attention to it. Through Retrouvaille, and through our everyday social interactions I talk with a lot of couples. I noticed a trend. Couples (gay or straight) in healthy relationships use each other’s names. Or they use pet names that may be a bit syrupy to the rest of us but reflect underlying love and respect for their partners. When things are strained in a relationship the other partner becomes a He or a She or a They. It’s almost as if they are using the third person to distance themselves from the other.

I’m pretty sure it is an unconscious act. But it matters. It’s also easier to criticize in the third person. If you don’t believe me, try not using the third person the next time you and a friend are complaining to each other about your respective partners. You’ll find it severely truncates the duration of the bitch session, and that’s not such a bad thing.

So even though Retrouvaille presenters are not marriage counselors, I do bend the “no marital advice” rule when I hear one spouse constantly refer to the other in the third person. Repairing a broken relationship requires a lot of personal change. I hope I’m giving them one change that isn’t too onerous but has a big payoff.

My Mum was a schoolteacher, and it would always bug me when she corrected my grammar. If I referred to my sister as ‘She’ my Mum would always come back with ‘She is the cat’s mother,’ please use your sister’s name. Little did I know she was giving me solid relationship advice.

Photo credit — Eric Ward