Categories
JavaScript

What’s New in ES2021?

ES2021 is the latest version of the EcmaScript specification as of 2021.

It has the newest features of JavaScript, which are being added into various runtime environments like browsers and Node.js.

In this article, we’ll look at the new features that come with ES2021.

String.prototype.replaceAll

The string instance’s replaceAll method is a new method that lets us replace all instances of a substring in a string.

To use it, we can write:

const newStr = 'foo bar foo bar'.replaceAll('foo', 'baz')
console.log(newStr)

Then newStr is 'baz bar baz bar’ .

We replace all instances of the string we passed in as the 1st argument with the string in the 2nd argument.

WeakRef

WeakRef is a constructor that lets us create objects that let us clean up whatever we pass into it manually.

For instance, we can write:

const obj = new WeakRef({
   foo: "bar"
 });
 console.log(obj.deref().foo);

We create a WeakRef instance by passing an object.

The constructor returns an object that has the same content as what we passed in.

But it also inherits the deref method that lets us remove the reference obj from memory manually.

deref returns the original content of obj .

So the console.log would log 'bar' .

Finalizers

Finalizers let us register callbacks that are run after an object is garbage collected.

For instance, we can write:

const registry = new FinalizationRegistry((value) => {
  console.log(value);
});

(() => {
  const obj = {}
  registry.register(obj, "bar");
})()

We create the registry with the FinalizationRegistry with a callback that’s called when an object that’s passed into registry.register is garbage collected.

We run the function that creates obj and pass that into registry.register with a value in the 2nd argument.

The value will be the value of value in the callback.

Therefore, we should see 'bar' logged after garbage collection is done on obj .

Promise.any()

Promise.any returns a promise that resolves if any supplied promise is resolved.

For instance, we can write:

(async () => {
  const result = await Promise.any([
    Promise.resolve(1),
    Promise.reject('error'),
    Promise.resolve(2)
  ]);
  console.log(result);
})();

We pass in an array of promises into Promise.any .

And since the first promise resolves to a value, Promise.any will return a promise that resolves to 1.

And result would therefore be 1.

If none of the promises resolves, then an AggregateError is raised.

So if we have something like:

(async () => {
  try {
    const result = await Promise.any([
      Promise.reject('error1'),
      Promise.reject('error2'),
      Promise.reject('error3'),
    ]);
    console.log(result);
  } catch (error) {
    console.log(error)
  }
})();

Then error would be 'AggregateError: All promises were rejected’ .

Logical Assignment Operator

With ES2021, we can combine the boolean operators && , || with the = operator to do the boolean operation on an existing variable with a new variable and assign it to the existing variable.

For instance, if we have:

let x = true;
const y = false;
x &&= y;
console.log(x)

Then x is false since x &&= y is the same as x = x && y .

We can do the same thing with || with the ||= operator.

Numeric Separator

The _ digit separator is now a standard in ES2021.

We can use _ to separate groups of digit for long numbers.

For instance, we can write 1_000_000 to write 1 million.

Conclusion

There’re many useful new features that comes with ES2021.

Categories
Vue 3

How to Call a Vue.js 3 Component Method from Outside the Component?

Sometimes, we may want to call a Vue 3 component method from outside the component.

In this article, we’ll look at how to call a Vue 3 component method from outside the component.

Assign a Ref to the Component and Call the Method From it

We can assign a ref to a component and get the method from the ref object and call it.

For instance, we can write:

App.vue

<template>
  <HelloWorld ref="helloWorld" />
  <button @click="greet">greet</button>
</template>

<script>
import HelloWorld from "./components/HelloWorld";

export default {
  name: "App",
  components: {
    HelloWorld,
  },
  methods: {
    greet() {
      this.$refs.helloWorld.greet("jane");
    },
  },
};
</script>

components/HelloWorld.vue

<template>
  <div>hello world</div>
</template>

<script>
export default {
  methods: {
    greet(name) {
      console.log(`hello world ${name}`);
    },
  },
};
</script>

We assign the helloWorld ref to the HelloWorld component.

Then we add the greet method that calls this.$refs.helloWorld.greet method which is the greet method from the HelloWorld component.

Therefore, we should see the 'hello world jane' logged when we click the greet button.

This lets us call a method in the child component from the parent.

Send an Event from the Child Component to the Parent

If we want to call a method in the parent component from the child component, then we should call the $emit method from the child component and listen to the event emitted by the child component in the parent component.

For instance, we can write:

App.vue

<template>
  <HelloWorld @greet="greet" />
</template>

<script>
import HelloWorld from "./components/HelloWorld";

export default {
  name: "App",
  components: {
    HelloWorld,
  },
  methods: {
    greet(name) {
      console.log(`hello world ${name}`);
    },
  },
};
</script>

components/HelloWorld.vue

<template>
  <div>hello world</div>
  <button @click="greet">greet</button>
</template>

<script>
export default {
  methods: {
    greet() {
      this.$emit("greet", "jane");
    },
  },
};
</script>

In HelloWorld.vue , we have the greet method which calls this.$emit with the event name as the first argument and the event payload as the 2nd argument.

Subsequent arguments are also event payloads which will be used as 2nd and subsequent arguments of the event handler method.

Then in App.vue , listen to the greet event with the @greet directive.

We set its value to greet to get the value we passed in as the 2nd argument.

So name is 'jane' .

And we should see 'hello world jane' logged when we click the greet button.

Conclusion

To call methods in a child component from the parent, we assign a ref to the component and get its methods from there.

If we want to call a method in the parent component from the child, then we emit an event in the child component and listen to that event in the parent component.

Categories
Vue 3

How to Get Query Parameters from a URL in Vue.js 3 with Vue Router 4?

Sometimes, we may want to add query parameters to route URLs so that we can get the query parameters in the component.

In this article, we’ll look at how to get query parameters from a URL in a Vue 3 app that uses Vue Router 4.

Get Query Parameters from a URL in Vue.js 3 with Vue Router 4

To get query parameter from a URL in a Vue 3 app that uses Vue Router 4, we can get the query parameters from the this.$route.query property.

main.js

import { createApp } from "vue";
import { createRouter, createWebHistory } from "vue-router";
import App from "./App.vue";
import Page1 from "./views/Page1";
import Page2 from "./views/Page2";
import Page3 from "./views/Page3";

const routes = [
  { path: "/", component: Page1 },
  { path: "/page2", component: Page2 },
  { path: "/page3", component: Page3 }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

const app = createApp(App);
app.use(router);
app.mount("#app");

App.vue

<template>
  <router-link to="/">page 1</router-link>
  <router-link to="/page2">page 2</router-link>
  <router-link to="/page3">page 3</router-link>
  <router-view></router-view>
</template>

<script>
export default {
  name: "App"
};
</script>

views/Page1.vue

<template>
  <div>page 1</div>
</template>

views/Page2.vue

<template>
  <div>page 2</div>
</template>

views/Page3.vue

<template>
  <div>page 3 {{ $route.query.foo }}</div>
</template>

<script>
export default {};
</script>

We set up the routes in main.js .

We import the page components and put them in the routes array.

Next, we call createRouter to create the router object.

Then we add the routes to the object we pass into createRouter ,

Then we have:

app.use(router);

to add the router to our app.

In Page3.vue , we have $router.query.foo in the template to get the foo query parameter.

This is the same as this.$router.query.foo in the component object.

In App.vue , we have the 3rd router-link ‘s to prop with a query string added after the path.

So when we click the link, we should see ‘bar’ displayed since we have foo=bar in the query string.

Conclusion

We can get query parameters in our Vue 3 app that uses Vue Router 4 with the this.$route.query property in a component.

Categories
Vue 3

How to Remove the Hash from the URL with Vue Router 4?

Sometimes, we want to map our components to paths that don’t have a hash in front of it in our Vue 3 app that uses Vue Router 4.

In this article, we’ll look at how to remove the hash from the URL path with Vue Router 4.

Remove the Hash from the URL with Vue Router 4

We can remove the hash from the URLs with Vue Router 4 by calling the createWebHistory method.

For instance, we can write:

main.js

import { createApp } from "vue";
import { createRouter, createWebHistory } from "vue-router";
import App from "./App.vue";
import Page1 from "./views/Page1";
import Page2 from "./views/Page2";
import Page3 from "./views/Page3";

const routes = [
  { path: "/", component: Page1 },
  { path: "/page2", component: Page2 },
  { path: "/page3", component: Page3 }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

const app = createApp(App);
app.use(router);
app.mount("#app");

App.vue

<template>
  <router-link to="/">page 1</router-link>
  <router-link to="/page2">page 2</router-link>
  <router-link to="/page3">page 3</router-link>
  <router-view></router-view>
</template>

<script>
export default {
  name: "App"
};
</script>

views/Page1.vue

<template>
  <div>page 1</div>
</template>

views/Page2.vue

<template>
  <div>page 2</div>
</template>

views/Page3.vue

<template>
  <div>page 3</div>
</template>

In main.js , we have the routes array with the route definitions.

We map the URL paths to components.

Then we call createRouter with an object that has the history property set to value returned by createWebHistory .

createWebHistory set the router to HTML5 history mode to remove the hash.

This will remove the hash from the paths that are mapped by Vue Router 4.

We also set the routes property to the routes array to add the routes we created.

Next, we call app.use with router to add the router object.

In App.vue , we have the router-link s to render the links.

router-view render the route page components.

Page1 , Page2 and Page3 are route components.

Now when we click on the router links, we shouldn’t see the hash in between the hostname and the route paths.

Conclusion

We can remove the hash from the URL with Vue Router 4’s createWebHistory function.

Categories
Vue 3

How to Disable Input Conditionally in Vue.js 3?

Sometimes, we may want to disable inputs conditionally in our Vue 3 apps.

In this article, we’ll look at how to disable input elements conditionally in Vue 3.

Disable Input Conditionally in Vue.js 3

We can disable inputs conditionally with Vue 3 by setting the disabled prop to the condition when we want to disable the input.

For instance, we can write:

<template>
  <input :disabled="disabled" />
  <button @click="disabled = !disabled">toggle disable</button>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      disabled: false,
    };
  },
};
</script>

We have the input with the disabled prop set to the disabled reactive property.

Below that, we have the @click directive to toggle the disabled reactive property when we click the button.

When disabled is true , then the input will be disabled.

So when we click the button repeatedly, the input will be disabled and enabled again.

Conclusion

We can conditionally disable an input with Vue 3 by setting the disabled prop of the input to an expression that has the condition of when we want to disable the input.