emGee Software Solutions Custom Database Applications

Share this

Web Technologies

Introduction to Bulma with React

Echo JS - Tue, 10/16/2018 - 04:43
Categories: Web Technologies

LoRa IoT Network Programming

Echo JS - Tue, 10/16/2018 - 04:43
Categories: Web Technologies

Getting Started with Nuxt.js

Echo JS - Tue, 10/16/2018 - 04:43
Categories: Web Technologies

Writing Redux in 15 lines of code

Echo JS - Tue, 10/16/2018 - 04:43
Categories: Web Technologies

CanJS Debugging Tutorial

Echo JS - Tue, 10/16/2018 - 04:43
Categories: Web Technologies

Nested Forms in Angular 6

Echo JS - Tue, 10/16/2018 - 04:43
Categories: Web Technologies

HTML for Zip Codes

CSS-Tricks - Mon, 10/15/2018 - 16:56

I just overheard this discussion on Twitter, kicked off by Dave.

Me (coding a form): <input id="zip" type="number">
Tiny Devil (appears on shoulder): Yaaas! I love the optimism, ship it!
Me: Wait, why are you here? Is this going to blow up on me? What do you know that I don't?

— Dave SPOOPert (@davatron5000) October 9, 2018

It seems like zip codes are just numbers, right? So...

<input id="zip" name="zip" type="number">

The advantage there being able to take advantage of free validation from the browser, and triggering a more helpful number-based keyboard on mobile devices.

But Zach pointed out that type="number" is problematic for zip codes because zip codes can have leading zeros (e.g. a Boston zip code might be 02119). Filament group also has a little lib for fixing this.

This is the perfect job for inputmode, as Jeremy suggests<input id="zip" name="zip" type="text" inputmode="numeric" pattern="^(?(^00000(|-0000))|(\d{5}(|-\d{4})))$">

But the support is pretty bad at the time of this writing.

A couple of people mentioned trying to hijack type="tel" for it, but that has its own downsides, like rejecting properly formatted 9-digit zip codes.

So, zip codes, while they look like numbers, are probably best treated as strings. Another option here is to leave it as a text input, but force numbers with pattern, as Pamela Fox documents:

<input id="zip" name="zip" type="text" pattern="[0-9]*">

The post HTML for Zip Codes appeared first on CSS-Tricks.

Categories: Web Technologies

Sass Selector Combining

CSS-Tricks - Mon, 10/15/2018 - 16:56

Brad Frost was asking about this the other day...

Sass people, which way do you do it and why? pic.twitter.com/dIBA9BIuCO

— Brad Frost (@brad_frost) October 1, 2018

.c-btn { &__icon { ... } }

I guess that's technically "nesting" but the selectors come out flat:

.c-button__icon { }

The question was whether you do that or just write out the whole selector instead, as you would with vanilla CSS. Brad's post gets into all the pro's and con's of both ways.

To me, I'm firmly in the camp of not "nesting" because it makes searching for selectors so much harder. I absolutely live by being able to search my project for fully expanded class names and, ironically, just as Brad was posting that poll, I was stumped by a combined class like this and changed it in one of my own code bases.

Robin Rendle also notes the difficulty in searching as an issue with an example that has clearly gone too far!

Direct Link to ArticlePermalink

The post Sass Selector Combining appeared first on CSS-Tricks.

Categories: Web Technologies

[Solved] MySQL User Operation - ERROR 1396 (HY000): Operation CREATE / DROP USER failed for 'user'@'host'

Planet MySQL - Mon, 10/15/2018 - 09:38
Error Message: ERROR 1396 (HY000): Operation CREATE USER failed for 'admin'@'%'
Generic Error Message: Operation %s failed for %s
Error Scenario: Operation CREATE USER failed
Operation DROP USER failed

Reason: The reason for this error is, you are trying to do some user operation but the user does not exist on the MySQL system. Also, for drop user, the user details are stored somewhere in the system, even though, you have already dropped the user from MySQL server.
Resolution: Revoke all access granted to the user, drop the user, and run FLUSH PRIVILEGE command to remove the caches. Now create/drop/alter the user, it will work.
REVOKE ALL ON *.* FROM 'user'@'host'; DROP USER 'user'@'host'; FLUSH PRIVILEGES;
Grant Tables: The following tables will help you in identifying the user related informations (as of MySQL 5.7):

mysql.user: User accounts, global privileges, and other non-privilege columns mysql.db: Database-level privileges mysql.tables_priv: Table-level privileges mysql.columns_priv: Column-level privileges mysql.procs_priv: Stored procedure and function privileges
mysql.proxies_priv: Proxy-user privilege
Related MySQL Bug Reports: https://bugs.mysql.com/bug.php?id=28331 https://bugs.mysql.com/bug.php?id=86523
I hope this post will help you, if you faced this error on some other scenarios or if you know, some other workaround / solution for this error, please add on the comment section. It will be helpful for other readers.

Categories: Web Technologies

Percona Live Europe Tutorial: Query Optimization and TLS at Large Scale

Planet MySQL - Mon, 10/15/2018 - 07:05

For Percona Live Europe this year, I got accepted a workshop on query optimization and a 50-minute talk covering TLS for MySQL at Large Scale, talking about our experiences at the Wikimedia Foundation.


The 3-hour workshop on Monday, titled Query Optimization with MySQL 8.0 and MariaDB 10.3: The Basics is a beginners’ tutorial–though dense in content. It’s for people who are more familiar with database storage systems other than InnoDB for MySQL, MariaDB or Percona Server. Or who, already familiar with them, are suffering performance and scaling issues with their SQL queries. If you get confused with the output of basic commands like EXPLAIN and SHOW STATUS and want to learn some SQL-level optimizations, such as creating the right indexes or altering the schema to get the most out of the performance of your database server, then you want to attend this tutorial before going into more advanced topics. Even veteran DBAs and developers may learn one or two new tricks, only available on the latest server versions!

Something that people may enjoy is that, during the tutorial, every attendee will be able to throw queries to a real-time copy of the Wikipedia database servers—or setup their own offline Wikipedia copy in their laptop. They’ll get practice by themselves what is being explained—so it will be fully hands-on. I like my sessions to be interactive, so all attendees should get ready to answer questions and think through the proposed problems by themselves!

Fifty minutes talk

My 50 minute talk TLS for MySQL at Large Scale will be a bit more advanced, although maybe more attractive to users of other database technologies. On Tuesday, I will tell the tale of the mistakes and lessons learned while deploying encryption (TLS/SSL) for the replication, administration, and client connections of our databases. At the Wikimedia Foundation we take very seriously the privacy of our users—Wikipedia readers, project contributors, data reusers and every members of our community—and while none of our databases are publicly reachable, our aim is to encrypt every single connection between servers, even within our datacenters.

However, when people talk about security topics, most of the time they are trying to show off the good parts of their set up, while hiding the ugly parts. Or maybe they are too theoretical to actually learn something. My focus will not be on the security principles everybody should follow, but on the pure operational problems, and the solutions we needed to deploy, as well what we would have done differently if we had known, while deploying TLS on our 200+ MariaDB server pool.

Looking forward…

For me, as an attendee, I always look forward to the ProxySQL sessions, as it is something we are currently deploying in our production. Also, I want to know more about the maturity and roadmap of the newest MySQL and MariaDB releases, as they keep adding new interesting features we need, as well as cluster technologies such as Galera and InnoDB Cluster. I like, too, to talk with people developing and using other technologies outside of my stack, and you never know when they will fill in a need we have (analytics, compression, NoSQL, etc.).

But above all, the thing I enjoy the most is the networking—being able to talk with professionals that suffer the same problems that I do is something I normally cannot do, and that I enjoy doing a lot during Percona Live.

Jaime Crespo in a Percona Live T-Shirt – why not come to this year’s event and start YOUR collection.

The post Percona Live Europe Tutorial: Query Optimization and TLS at Large Scale appeared first on Percona Community Blog.

Categories: Web Technologies

Lazy Loading Images with Vue.js Directives and Intersection Observer

CSS-Tricks - Mon, 10/15/2018 - 07:00

When I think about web performance, the first thing that comes to my mind is how images are generally the last elements that appear on a page. Today, images can be a major issue when it comes to performance, which is unfortunate since the speed a website loads has a direct impact on users successfully doing what they came to the page to do (think conversation rates).

Very recently, Rahul Nanwani wrote up an extensive guide on lazy loading images. I’d like to cover the same topic, but from a different approach: using data attributes, Intersection Observer and custom directives in Vue.js.

What this’ll basically do is allow us to solve two things:

  1. Store the src of the image we want to load without loading it in the first place.
  2. Detect when the image becomes visible to the user and trigger the request to load the image.

Same basic lazy loading concept, but another way to go about it.

I created an example, based on an example described by Benjamin Taylor in his blog post. It contains a list of random articles each one containing a short description, image, and a link to the source of the article. We will go through the process of creating a component that is in charge of displaying that list, rendering an article, and lazy loading the image for a specific article.

Let’s get lazy! Or at least break this component down piece-by-piece.

Step 1: Create the ImageItem component in Vue

Let’s start by creating a component that will show an image (but with no lazy loading involved just yet). We’ll call this file ImageItem.vue. In the component template, we’ll use a figure tag that contains our image — the image tag itself will receive the src attribute that points to the source URL for the image file.

<template> <figure class="image__wrapper"> <img class="image__item" :src="source" alt="random image" > </figure> </template>

In the script section of the component, we receive the prop source that we’ll use for the src url of the image we are displaying.

export default { name: "ImageItem", props: { source: { type: String, required: true } } };

All this is perfectly fine and will render the image normally as is. But, if we leave it here, the image will load straight away without waiting for the entire component to be render. That’s not what we want, so let’s go to the next step.

Step 2: Prevent the image from being loaded when the component is created

It might sound a little funny that we want to prevent something from loading when we want to show it, but this is about loading it at the right time rather than blocking it indefinitely. To prevent the image from being loaded, we need to get rid of the src attribute from the img tag. But, we still need to store it somewhere so we can make use of it when we want it. A good place to keep that information is in a data- attribute. These allow us to store information on standard, semantic HTML elements. In fact, you may already be accustomed to using them as JavaScript selectors.

In this case, they’re a perfect fit for our needs!

<!--ImageItem.vue--> <template> <figure class="image__wrapper"> <img class="image__item" :data-url="source" // yay for data attributes! alt="random image" > </figure> </template>

With that, our image will not load because there is no source URL to pull from.

That’s a good start, but still not quite what we want. We want to load our image under specific conditions. We can request the image to load by replacing the src attribute with the image source URL kept in our data-url attribute. That’s the easy part. The real challenge is figuring out when to replace it with the actual source.

Our goal is to pin the load to the user’s screen location. So, when the user scrolls to a point where the image comes into view, that’s where it loads.

How can we detect if the image is in view or not? That’s our next step.

Step 3: Detect when the image is visible to the user

You may have experience using JavaScript to determine when an element is in view. You may also have experience winding up with some gnarly script.

For example, we could use events and event handlers to detect the scroll position, offset value, element height, and viewport height, then calculate whether an image is in the viewport or not. But that already sounds gnarly, doesn’t it?

But it could get worse. This has direct implications on performance. Those calculations would be fired on every scroll event. Even worse, imagine a few dozen images, each having to recalculate whether it is visible or not on each scroll event. Madness!

Intersection Observer to the rescue! This provides a very efficient way of detecting if an element is visible in the viewport. Specifically, it allows you to configure a callback that is triggered when one element — called the target — intersects with either the device viewport or a specified element.

So, what we need to do to use it? A few things:

  • create a new intersection observer
  • watch the element we wish to lazy load for visibility changes
  • load the element when the element is in viewport (by replacing src with our data-url)
  • stop watching for visibility changes (unobserve) after the load completes

Vue.js has custom directives to wrap all this functionality together and use it when we need it, as many times as we need it. Putting that to use is our next step.

Step 4: Create a Vue custom directive

What is a custom directive? Vue’s documentation describes it as a way to get low-level DOM access on elements. For example, changing an attribute of a specific DOM element which, in our case, could be changing the src attribute of an img element. Perfect!

We’ll break this down in a moment, but here’s what we’re looking at as far as the code:

export default { inserted: el => { function loadImage() { const imageElement = Array.from(el.children).find( el => el.nodeName === "IMG" ); if (imageElement) { imageElement.addEventListener("load", () => { setTimeout(() => el.classList.add("loaded"), 100); }); imageElement.addEventListener("error", () => console.log("error")); imageElement.src = imageElement.dataset.url; } } function handleIntersect(entries, observer) { entries.forEach(entry => { if (entry.isIntersecting) { loadImage(); observer.unobserve(el); } }); } function createObserver() { const options = { root: null, threshold: "0" }; const observer = new IntersectionObserver(handleIntersect, options); observer.observe(el); } if (window["IntersectionObserver"]) { createObserver(); } else { loadImage(); } } };

OK, let’s tackle this step-by-step.

The hook function allows us to fire a custom logic at a specific moment of a bound element lifecycle. We use the inserted hook because it is called when the bound element has been inserted into its parent node (this guarantees the parent node is present). Since we want to observe visibility of an element in relation to its parent (or any ancestor), we need to use that hook.

export default { inserted: el => { ... } }

The loadImage function is the one responsible for replacing the src value with data-url. In it, we have access to our element (el) which is where we apply the directive. We can extract the img from that element.

Next, we check if the image exists and, if it does, we add a listener that will fire a callback function when the loading is finished. That callback will be responsible for hiding the spinner and adding the animation (fade-in effect) to the image using a CSS class. We also add a second listener that will be called in the event that the URL fails to load.

Finally, we replace the src of our img element with the source URL of the image and show it!

function loadImage() { const imageElement = Array.from(el.children).find( el => el.nodeName === "IMG" ); if (imageElement) { imageElement.addEventListener("load", () => { setTimeout(() => el.classList.add("loaded"), 100); }); imageElement.addEventListener("error", () => console.log("error")); imageElement.src = imageElement.dataset.url; } }

We use Intersection Observer’s handleIntersect function, which is responsible for firing loadImage when certain conditions are met. Specifically, it is fired when Intersection Observer detects that the element enters the viewport or a parent component element.

The function has access to entries, which is an array of all elements that are watched by the observer and observer itself. We iterate through entries and check if a single entry becomes visible to our user with isIntersecting — and fire the loadImage function if it is. Once the image is requested, we unobserve the element (remove it from the observer’s watch list), which prevents the image from being loaded again. And again. And again. And…

function handleIntersect(entries, observer) { entries.forEach(entry => { if (entry.isIntersecting) { loadImage(); observer.unobserve(el); } }); }

The last piece is the createObserver function. This guy is responsible for creating our Intersection Observer and attaching it to our element. The IntersectionObserver constructor accepts a callback (our handleIntersect function) that is fired when the observed element passes the specified threshold and the options object that carries our observer options.

Speaking of the options object, it uses root as our reference object, which we use to base the visibility of our watched element. It might be any ancestor of the object or our browser viewport if we pass null. The object also specifies a threshold value that can vary from 0 to 1 and tells us at what percent of the target’s visibility the observer callback should be executed, with 0 meaning as soon as even one pixel is visible and 1 meaning the whole element must be visible.

And then, after creating the Intersection Observer, we attach it to our element using the observe method.

function createObserver() { const options = { root: null, threshold: "0" }; const observer = new IntersectionObserver(handleIntersect, options); observer.observe(el); } Step 5: Registering directive

To use our newly created directive, we first need to register it. There are two ways to do it: globally (available everywhere in the app) or locally (on a specified component level).

Global registration

For global registration, we import our directive and use the Vue.directive method to pass the name we want to call our directive and directive itself. That allows us to add a v-lazyload attribute to any element in our code.

// main.js import Vue from "vue"; import App from "./App"; import LazyLoadDirective from "./directives/LazyLoadDirective"; Vue.config.productionTip = false; Vue.directive("lazyload", LazyLoadDirective); new Vue({ el: "#app", components: { App }, template: "<App/>" }); Local registration

If we want to use our directive only in a specific component and restrict the access to it, we can register the directive locally. To do that, we need to import the directive inside the component that will use it and register it in the directives object. That will give us the ability to add a v-lazyload attribute to any element in that component.

import LazyLoadDirective from "./directives/LazyLoadDirective"; export default { directives: { lazyload: LazyLoadDirective } } Step 6: Use a directive on the ImageItem component

Now that our directive has been registered, we can use it by adding v-lazyload on the parent element that carries our image (the figure tag in our case).

<template> <figure v-lazyload class="image__wrapper"> <ImageSpinner class="image__spinner" /> <img class="image__item" :data-url="source" alt="random image" > </figure> </template> Browser Support

We’d be remiss if we didn’t make a note about browser support. Even though the Intersection Observe API it is not supported by all browsers, it does cover 73% of users (as of this writing).

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

DesktopChromeOperaFirefoxIEEdgeSafari584555No16NoMobile / TabletiOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid FirefoxNo46No676962

Not bad. Not bad at all.

But! Having in mind that we want to show images to all users (remember that using data-url prevents the image from being loaded at all), we need to add one more piece to our directive. Specifically, we need to check if the browser supports Intersection Observer, and it it doesn’t, fire loadImage instead. This will be our fallback.

if (window["IntersectionObserver"]) { createObserver(); } else { loadImage(); } Summary

Lazy loading images can significantly improve page performance because it takes the page weight hogged by images and loads them in only when the user actually needs them.

For those still not convinced if it is worth playing with lazy loading, here’s some raw numbers from the simple example we’ve been using. The list contains 11 articles with one image per article. That’s a total of 11 images (math!). It’s not like that’s a ton of images but we can still work with it.

Here’s what we get rending all 11 images without lazy loading on a 3G connection:

The 11 image requests contribute to an overall page size of 3.2 MB. Oomph.

Here’s the same page putting lazy loading to task:

Say what? Only one request for one image. Our page is now 1.4 MB. We saved 10 requests and reduced the page size by 56%.

Is it a simple and isolated example? Yes, but the numbers still speak for themselves. Hopefully you find lazy loading an effective way to fight the battle against page bloat and that this specific approach using Vue with Intersection Observer comes in handy.

The post Lazy Loading Images with Vue.js Directives and Intersection Observer appeared first on CSS-Tricks.

Categories: Web Technologies