Categories
JavaScript Mistakes

Common JavaScript Mistakes — Part 3

JavaScript is a language that’s friendlier than many other programming languages in the world. However, it’s still very easy to make mistakes when writing JavaScript code through misunderstanding or overlooking stuff that we already know. By avoiding some of the mistakes below, we can make our lives easier by preventing bugs and typos in our code that bog us down with unexpected results.


Trying to Overload Functions

Functional overloading is a feature of some programming languages where you can declare functions with the same name but different signatures. In JavaScript, we can’t overload functions. Whenever a function is declared more than once, the one that is declared later overwrites the one that’s declared earlier. This is because functions are objects and declaring a function is like assigning an object to a variable. When you assign an object to a variable more than once, then the value that’s assigned later will overwrite the value that’s assigned earlier. That means that we can’t have two functions with the same name in the same module in JavaScript. For example, if we have the following,

function add(a, b, c) {
  return a + b + c;
}

function add(a, b) {
  return a + b;
}

console.log(add(1, 2, 3));

then we get three because the add function that’s declared later has overwritten the one that’s declared earlier. To fix this, we have to rename one of them. We can also put them inside two different objects. Then they can have the same name since they aren’t in the same level. Also, we can write an Immediately Invoked Function Expression, or IIFE for short. IIFEs are run as soon as they’re defined. To wrap them in an object, we can write the following:

const a = {
  add(a, b, c) {
    return a + b + c;
  }
}

const b = {
  add(a, b) {
    return a + b;
  }
}

console.log(a.add(1, 2, 3));
console.log(b.add(1, 2, 3));

As we can see, if we run the code, then the console.log of the first one will be six and the second one will be three since a.add has three parameters and b.add has two.

We can also use an IIFE as in the following example:

const sum1 = (function add(a, b, c) {
  return a + b + c;
})(1, 2, 3);

const sum2 = (function add(a, b) {
  return a + b;
})(1, 2, 3);

console.log(sum1);
console.log(sum2);

In the code above, we wrapped the function inside the parentheses and then called it immediately after it was defined. Then we assigned the returned result to a variable. After that, we get six and three as we wanted. Because we called each function immediately and returned the result, we get the right result since they didn’t overlap. It also means that they can’t be called again.


Missing Parameters

When we add a new parameter to a function, then we have to remember to pass in the extra argument in the function calls. Otherwise, there may be undefined errors. To avoid undefined parameters creating errors, we can either check for it in our function, or we can set a default value of the parameter. For example, if we have the following function

function addressFn(address, city, region) { ... }

and we want to add a countryparameter and we have other parts of our program calling the function above, then we can add a default parameter. We can do this by writing the following:

function addressFn(address, city, region, country = 'US') { ... }

This way, if the country argument didn’t get passed in, country will be set to 'US'.

Photo by Kendall Lane on Unsplash


Forgetting About the this Keyword

When we try to access some property from another property inside an object, we should use the this keyword to get the property’s value that we want. For example, if we have the following,

let obj = {
  prop: "some text",
  method() {
    console.log(prop);
  }
};

obj.method();

we will get an Uncaught ReferenceError: prop is not defined error when we run the code above. This is because we forgot to put the this keyword before the prop variable. Instead, we need to write the following:

let obj = {
  prop: "some text",
  method() {
    console.log(this.prop);
  }
};

obj.method();

When we run the code above, then we get 'some text', which is what we wanted.


Iterate Through the Object Keys

The for...in loop will loop through the keys of the current object as well as all the prototypes’ keys. This isn’t ideal for all situations. It’s also slower than the other ways of iterating through the keys of an object. With the for...in loop, we need to use the Object.hasOwnProperty function to check that the property is originally defined in the object. This makes the loop even slower. This is a problem if we have a large object with lots of properties. For example, if we have,

const parent = {
  pa: 1,
  pb: 2
}
let obj = Object.create(parent);

obj.a = 1;
obj.b = 2;
obj.c = 3;
obj.d = 4;
obj.e = 5;

then the for...in loop will loop through all the properties of the parent and the properties added to obj. If we only want to loop through the properties in obj, then we have to loop using the hasOwnProperty function as in the following code:

for (const key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(obj[key]);
  }
}

However, this is slower than the newer alternatives, which are Object.keys to get the keys of an object and Object.entries to get the key-value pairs of an object. Then we loop through them with the for...of loop since both return arrays. They only loop through the object’s properties and nothing up the prototype chain. The fastest ways to loop through the entries are these two functions. We can use them as follows:

const parent = {
  pa: 1,
  pb: 2
}
let obj = Object.create(parent);

obj.a = 1;
obj.b = 2;
obj.c = 3;
obj.d = 4;
obj.e = 5;

for (const key of Object.keys(obj)) {
  console.log(obj[key]);
}

for (const [key, value] of Object.entries(obj)) {
  console.log(value);
}

In each example, we get the following logged,

a 1
b 2
c 3
d 4
e 5

which means that we’re getting what we want from the Object.keys and Object.entries functions.


Even though JavaScript is a friendly language, it’s still very easy to make mistakes when writing JavaScript code. Remember that in JavaScript, we can’t overload functions, so we can’t define two functions with the same name in the same level. If there’s potential for a function parameter to not be set, then we can set a default parameter so that it will never be undefined. Also, we can’t forget about the this object when we’re accessing one property from another property of the same object. Finally, we shouldn’t use the for...in loop anymore to loop through the keys of an object because it’s slow and clunky if we just want to loop through the keys of the current object without its prototype’s keys. We want to use the Object.keys or Object.entries functions instead so we get the keys or the key-value pairs, respectively, as arrays, and we can loop through them like any other array.

Categories
Vuetify

Vuetify — Item Groups

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Item Groups

We can add group items with the v-item-group component.

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-item-group multiple>
          <v-container>
            <v-row>
              <v-col v-for="n in 3" :key="n" cols="12" md="4">
                <v-item v-slot:default="{ active, toggle }">
                  <v-card
                    :color="active ? 'primary' : ''"
                    class="d-flex align-center"
                    dark
                    height="200"
                    @click="toggle"
                  >
                    <v-scroll-y-transition>
                      <div v-if="active" class="display-3 flex-grow-1 text-center">Active</div>
                    </v-scroll-y-transition>
                  </v-card>
                </v-item>
              </v-col>
            </v-row>
          </v-container>
        </v-item-group>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

We populate the default slot of v-item with our own content.

active is a boolean which indicates whether the item is pressed or not.

toggle is a function that we can click to make the item active.

Active Class

We can set the active class with active-class prop on the v-item-group .

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-item-group active-class="primary">
          <v-container>
            <v-row>
              <v-col v-for="n in 3" :key="n" cols="12" md="4">
                <v-item v-slot:default="{ active, toggle }">
                  <v-card class="d-flex align-center" dark height="200" @click="toggle">
                    <v-scroll-y-transition>
                      <div v-if="active" class="display-3 flex-grow-1 text-center">Active</div>
                    </v-scroll-y-transition>
                  </v-card>
                </v-item>
              </v-col>
            </v-row>
          </v-container>
        </v-item-group>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

We set the active-class to primary to set the class when active is true .

Chips

We can add a custom chip group with the v-item component.

For instance, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-item-group multiple>
          <v-subheader>Tags</v-subheader>
          <v-item v-for="n in 8" :key="n" v-slot:default="{ active, toggle }">
            <v-chip active-class="purple--text" :input-value="active" @click="toggle">Tag {{ n }}</v-chip>
          </v-item>
        </v-item-group>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

to add a bunch of chips within a v-item-group .

List Item Groups

We can group list items into a group.

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-list flat>
          <v-list-item-group v-model="model" color="indigo">
            <v-list-item v-for="(item, i) in items" :key="i">
              <v-list-item-icon>
                <v-icon v-text="item.icon"></v-icon>
              </v-list-item-icon>

              <v-list-item-content>
                <v-list-item-title v-text="item.text"></v-list-item-title>
              </v-list-item-content>
            </v-list-item>
          </v-list-item-group>
        </v-list>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        icon: "mdi-wifi",
        text: "Wifi",
      },
      {
        icon: "mdi-bluetooth",
        text: "Bluetooth",
      },
      {
        icon: "mdi-chart-donut",
        text: "Data Usage",
      },
    ],
  }),
};
</script>

We use the v-list component to add a list.

Then we add a v-list-item-group to add the items.

v-list-item-icon adds the icon.

And v-list-item-content adds the content for the list item.

Conclusion

We can add list items and item groups with Vuetify.

Categories
Vuetify

Vuetify — Chip Groups

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Chip Groups

We can group chips together with the v-chip-group component.

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-sheet elevation="10" class="pa-4">
          <v-chip-group column active-class="primary--text">
            <v-chip v-for="tag in tags" :key="tag">{{ tag }}</v-chip>
          </v-chip-group>
        </v-sheet>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    tags: ["mango", "apple", "orange", "pear", "grape"],
  }),
};
</script>

We put the v-chip components in the v-chip-group component.

Mandatory

We can add the mandatory prop so that there’s a value selected.

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-sheet elevation="10" class="py-4 px-1">
          <v-chip-group mandatory active-class="primary--text">
            <v-chip v-for="tag in tags" :key="tag">{{ tag }}</v-chip>
          </v-chip-group>
        </v-sheet>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    tags: ["mango", "apple", "orange", "pear", "grape"],
  }),
};
</script>

We put the mandatory prop on the v-chip-group component.

Multiple

The multiple prop lets us select multiple chips.

For instance, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-sheet elevation="10" class="py-4 px-1">
          <v-chip-group multiple active-class="primary--text">
            <v-chip v-for="tag in tags" :key="tag">{{ tag }}</v-chip>
          </v-chip-group>
        </v-sheet>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    tags: ["mango", "apple", "orange", "pear", "grape"],
  }),
};
</script>

then we can select multiple chips.

Filter Results

Chips can have additional feedback with the filter prop.

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-card class="mx-auto" max-width="400">
          <v-card-text>
            <h2 class="title mb-2">Choose fruits</h2>

            <v-chip-group v-model="fruits" column multiple>
              <v-chip filter outlined>apple</v-chip>
              <v-chip filter outlined>orange</v-chip>
              <v-chip filter outlined>grape</v-chip>
            </v-chip-group>
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    fruits: [],
  }),
};
</script>

to add chips that show a checkmark when it’s chosen.

v-model will bind the selected items to the model.

filter is what makes the checkmark shown.

outlined makes the chip displayed with a white background when it’s not selected.

Conclusion

We can add chip groups to show a group of chips that we can select.

Categories
Vuetify

Vuetify — Button Groups

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Button Groups

The v-btn-toggle component is a wrapper for v-item-group that works with v-btn components.

We can use it to add a group of buttons that can be toggled.

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-card flat class="py-12">
          <v-card-text>
            <v-row align="center" justify="center">
              <v-btn-toggle v-model="toggle" rounded>
                <v-btn>
                  <v-icon>mdi-format-align-left</v-icon>
                </v-btn>
                <v-btn>
                  <v-icon>mdi-format-align-center</v-icon>
                </v-btn>
                <v-btn>
                  <v-icon>mdi-format-align-right</v-icon>
                </v-btn>
                <v-btn>
                  <v-icon>mdi-format-align-justify</v-icon>
                </v-btn>
              </v-btn-toggle>
            </v-row>
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    toggle: undefined,
  }),
};
</script>

to add a button group with the v-btn-toggle component.

We just put the v-btn components inside the group.

The rounded prop makes the button group round.

Mandatory Button Groups

The mandatory prop makes the v-btn-toggle always has a value.

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-card flat class="py-12">
          <v-card-text>
            <v-row align="center" justify="center">

            <v-btn-toggle v-model="toggle" multiple>
                <v-btn>
                  <v-icon>mdi-format-align-left</v-icon>
                </v-btn>
                <v-btn>
                  <v-icon>mdi-format-align-center</v-icon>
                </v-btn>
                <v-btn>
                  <v-icon>mdi-format-align-right</v-icon>
                </v-btn>
                <v-btn>
                  <v-icon>mdi-format-align-justify</v-icon>
                </v-btn>
              </v-btn-toggle>

              <v-col cols="12" class="text-center">{{ toggle }}</v-col>
            </v-row>
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    toggle: []
  }),
};
</script>

The multiple prop lets us make multiple selections.

When we click on a button, the index of it will be added to the state.

Buttons in a Toolbar

We can add buttons to the v-toolbar .

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-toolbar dense>
          <v-overflow-btn :items="dropdownFont" label="Select font" hide-details class="pa-0"></v-overflow-btn>
          <template v-if="$vuetify.breakpoint.mdAndUp">
            <v-divider vertical></v-divider>
            <v-overflow-btn
              :items="dropdownEdit"
              editable
              label="Select size"
              hide-details
              class="pa-0"
              overflow
            ></v-overflow-btn>
            <v-divider vertical></v-divider>
            <v-spacer></v-spacer>
            <v-btn-toggle v-model="toggleMultiple" color="primary" dense group multiple>
              <v-btn :value="1" text>
                <v-icon>mdi-format-bold</v-icon>
              </v-btn>
              <v-btn :value="2" text>
                <v-icon>mdi-format-italic</v-icon>
              </v-btn>
              <v-btn :value="3" text>
                <v-icon>mdi-format-underline</v-icon>
              </v-btn>
            </v-btn-toggle>
            <div class="mx-4"></div>
            <v-btn-toggle v-model="toggleExclusive" color="primary" dense group>
              <v-btn :value="1" text>
                <v-icon>mdi-format-align-left</v-icon>
              </v-btn>
              <v-btn :value="2" text>
                <v-icon>mdi-format-align-center</v-icon>
              </v-btn>
              <v-btn :value="3" text>
                <v-icon>mdi-format-align-right</v-icon>
              </v-btn>
            </v-btn-toggle>
          </template>
        </v-toolbar>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    dropdownFont: [
      { text: "Arial" },
      { text: "Calibri" },
      { text: "Courier" },
      { text: "Verdana" },
    ],
    dropdownEdit: [
      { text: "100%" },
      { text: "75%" },
      { text: "50%" },
      { text: "25%" },
      { text: "0%" },
    ],
    toggleExclusive: 2,
    toggleMultiple: [1, 2, 3],
  }),
};
</script>

We have the v-toolbar with the v-overflow-btn components to add the dropdowns.

And we add the v-divider to add the dividers to our toolbar.

v-btn-toggle lets us add the button toggles.

Also, we added the dense prop to make the toolbar smaller.

Conclusion

We can add button groups to toolbars and more with Vuetify.

Categories
Vuetify

Vuetify — Column Spacing and Ordering

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Order Last or First

We can set the order prop to last and first to set the columns to last and first.

For example, we can write:

<template>  
  <v-container class="grey lighten-5">  
    <v-row no-gutters>  
      <v-col order="last">  
        <v-card class="pa-2" outlined tile>First, but last</v-card>  
      </v-col>  
      <v-col>  
        <v-card class="pa-2" outlined tile>Second, but unordered</v-card>  
      </v-col>  
      <v-col order="first">  
        <v-card class="pa-2" outlined tile>Third, but first</v-card>  
      </v-col>  
    </v-row>  
  </v-container>  
</template>  
<script>  
export default {  
  name: "HelloWorld",  
  data: () => ({}),  
};  
</script>

Offset

We can use the offset props to add spaces between columns.

For example, we can write:

<template>  
  <v-container class="grey lighten-5">  
    <v-row class="mb-6" no-gutters>  
      <v-col md="4">  
        <v-card class="pa-2" outlined tile>.col-md-4</v-card>  
      </v-col>  
      <v-col md="2" offset-md="6">  
        <v-card class="pa-2" outlined tile>.col-md-2 .offset-md-6</v-card>  
      </v-col>  
    </v-row>  
  </v-container>  
</template>  
<script>  
export default {  
  name: "HelloWorld",  
  data: () => ({}),  
};  
</script>

We have the offset-md prop to set the number of columns between this and the div before it when the md breakpoint is hit.

Margin Utilities

We can add padding and margin to columns.

For example, we can write:

<template>  
  <v-container class="grey lighten-5">  
    <v-row>  
      <v-col md="4">  
        <v-card class="pa-2" outlined tile>.col-md-4</v-card>  
      </v-col>  
      <v-col md="4" class="ml-auto">  
        <v-card class="pa-2" outlined tile>.col-md-4 .ml-auto</v-card>  
      </v-col>  
    </v-row>  
  </v-container>  
</template>  
<script>  
export default {  
  name: "HelloWorld",  
  data: () => ({}),  
};  
</script>

The pa-2 class adds padding around the classes.

ml-auto adds margin between the v-col components.

Nested Grid

We can create a grid that’s nested in a parent grid.

For instance, we can write:

<template>  
  <v-container class="grey lighten-5">  
    <v-row>  
      <v-col sm="9">  
        <v-card class="pa-2" outlined tile>Level 1</v-card>  
        <v-row no-gutters>  
          <v-col cols="8" sm="6">  
            <v-card class="pa-2" outlined style="background-color: lightgrey;" tile>Level 2</v-card>  
          </v-col>  
          <v-col cols="4" sm="6">  
            <v-card class="pa-2" outlined style="background-color: lightgrey;" tile>Level 3</v-card>  
          </v-col>  
        </v-row>  
      </v-col>  
    </v-row>  
  </v-container>  
</template>  
<script>  
export default {  
  name: "HelloWorld",  
  data: () => ({}),  
};  
</script>

And we have v-row s inside v-col s to nest them.

Spacers

The v-spacer component is useful when we fill available space or make space between 2 components.

For example, we can write:

<template>  
  <v-container class="grey lighten-5">  
    <v-row>  
      <v-col>  
        <v-card class="pa-2" outlined tile>.col</v-card>  
      </v-col>  
      <v-spacer></v-spacer>  
      <v-col>  
        <v-card class="pa-2" outlined tile>.col</v-card>  
      </v-col>  
      <v-spacer></v-spacer>  
      <v-col>  
        <v-card class="pa-2" outlined tile>.col</v-card>  
      </v-col>  
    </v-row>  
  </v-container>  
</template>  
<script>  
export default {  
  name: "HelloWorld",  
  data: () => ({}),  
};  
</script>

to add the v-spacer component to space out the v-col s evenly.

Conclusion

We can order columns and space them out the way we like with various props.