utf8_general_ci and utf8_unicode_ci

 Update in 2019-10-29

As mentions by @Manuel Jordan in comments, utf8mb4_0900_ai_ci is the new default in MySQL 8.0, so the following is now again a better practice:

CREATE DATABASE mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;

Answer before 2019-10-29
Note: The following is now considered a better practice (see bikeman868's answer):

CREATE DATABASE mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;



MySQL is currently transitioning away from an older, flawed UTF-8 implementation. For now, you need to use utf8mb4 instead of utf8 for the character encoding part, to ensure you are getting the fixed version. The flawed version remains for backward compatibility, though it is being deprecated.

Key differences

  • utf8mb4_unicode_ci is based on the official Unicode rules for universal sorting and comparison, which sorts accurately in a wide range of languages.

  • utf8mb4_general_ci is a simplified set of sorting rules which aims to do as well as it can while taking many short-cuts designed to improve speed. It does not follow the Unicode rules and will result in undesirable sorting or comparison in some situations, such as when using particular languages or characters.

    On modern servers, this performance boost will be all but negligible. It was devised in a time when servers had a tiny fraction of the CPU performance of today's computers.

Benefits of utf8mb4_unicode_ci over utf8mb4_general_ci

utf8mb4_unicode_ci, which uses the Unicode rules for sorting and comparison, employs a fairly complex algorithm for correct sorting in a wide range of languages and when using a wide range of special characters. These rules need to take into account language-specific conventions; not everybody sorts their characters in what we would call 'alphabetical order'.

As far as Latin (ie "European") languages go, there is not much difference between the Unicode sorting and the simplified utf8mb4_general_ci sorting in MySQL, but there are still a few differences:

  • For examples, the Unicode collation sorts "ß" like "ss", and "Œ" like "OE" as people using those characters would normally want, whereas utf8mb4_general_ci sorts them as single characters (presumably like "s" and "e" respectively).

  • Some Unicode characters are defined as ignorable, which means they shouldn't count toward the sort order and the comparison should move on to the next character instead. utf8mb4_unicode_ci handles these properly.

In non-latin languages, such as Asian languages or languages with different alphabets, there may be a lot more differences between Unicode sorting and the simplified utf8mb4_general_ci sorting. The suitability of utf8mb4_general_ci will depend heavily on the language used. For some languages, it'll be quite inadequate.

What should you use?

There is almost certainly no reason to use utf8mb4_general_ci anymore, as we have left behind the point where CPU speed is low enough that the performance difference would be important. Your database will almost certainly be limited by other bottlenecks than this.

In the past, some people recommended to use utf8mb4_general_ci except when accurate sorting was going to be important enough to justify the performance cost. Today, that performance cost has all but disappeared, and developers are treating internationalization more seriously.

There's an argument to be made that if speed is more important to you than accuracy, you may as well not do any sorting at all. It's trivial to make an algorithm faster if you do not need it to be accurate. So, utf8mb4_general_ci is a compromise that's probably not needed for speed reasons and probably also not suitable for accuracy reasons.

One other thing I'll add is that even if you know your application only supports the English language, it may still need to deal with people's names, which can often contain characters used in other languages in which it is just as important to sort correctly. Using the Unicode rules for everything helps add peace of mind that the very smart Unicode people have worked very hard to make sorting work properly.

Function in JavaScript that can be called only once

 https://stackoverflow.com/questions/12713564/function-in-javascript-that-can-be-called-only-once

If by "won't be executed" you mean "will do nothing when called more than once", you can create a closure:

var something = (function() {
    var executed = false;
    return function() {
        if (!executed) {
            executed = true;
            // do something
        }
    };
})();

something(); // "do something" happens
something(); // nothing happens

In answer to a comment by @Vladloffe (now deleted): With a global variable, other code could reset the value of the "executed" flag (whatever name you pick for it). With a closure, other code has no way to do that, either accidentally or deliberately.

As other answers here point out, several libraries (such as Underscore and Ramda) have a little utility function (typically named once()[*]) that accepts a function as an argument and returns another function that calls the supplied function exactly once, regardless of how many times the returned function is called. The returned function also caches the value first returned by the supplied function and returns that on subsequent calls.

However, if you aren't using such a third-party library, but still want a utility function (rather than the nonce solution I offered above), it's easy enough to implement. The nicest version I've seen is this one posted by David Walsh:

function once(fn, context) { 
    var result;
    return function() { 
        if (fn) {
            result = fn.apply(context || this, arguments);
            fn = null;
        }
        return result;
    };
}

I would be inclined to change fn = null; to fn = context = null;. There's no reason for the closure to maintain a reference to context once fn has been called.

Usage:

function something() { /* do something */ }
var one_something = once(something);

one_something(); // "do something" happens
one_something(); // nothing happens

Using the OptinMonster API with Single Page Applications

 https://optinmonster.com/docs/using-the-optinmonster-api-with-single-page-applications/

OptinMonster works on almost any website, including Single Page Applications.

In this article, we’ll provide some examples for using the Events API .reset() method to work with the OptinMonster API to deeply integrate with your Single Page Application.

Before You Start

Here are some things to know before you begin:

  • Due to the advanced nature of this guide, at this time we do not provide technical support for implementing .reset() in Single Page Applications.

Examples

You would update any of the following examples’ method to use your own unique OptinMonster account ID and user ID.

The method is formatted based on your account and user id: om{accountId}_{userId} so if your account ID is 1234 and your user ID 5678 the object would be window.om5678_1234.

Vue Router
1// Using Vue Router.
2import Vue from 'vue';
3import Router from 'vue-router';
4Vue.use(Router);
5const router = new Router ({
6// Your vue router settings.
7});
8router.beforeEach((to, from, next) => {
9    if (window.om5678_1234) {
10        window.om5678_1234.reset();
11    }
12});
13export default router;
React Router V4
1// Using React Router V4
2import React from "react";
3import { withRouter } from "react-router";
4class App extends Component {
5    componentDidMount() {
6        this.unlisten = this.props.history.listen((location, action) => {
7            if (window.om5678_1234) {
8                window.om5678_1234.reset();
9            }
10        });
11    }
12    componentWillUnmount() {
13        this.unlisten();
14    }
15    render() {
16        return (
17             
18 
19<div>{/* Your routes defined here. */}</div>
20 
21 
22        );
23    }
24}
25export default withRouter(App);
React Router V3
1// Using React Router V3
2import { browserHistory } from 'react-router';
3class App extends React.component {
4    componentDidMount() {
5        this.unlisten = browserHistory.listen( location => {
6            if (window.om5678_1234) {
7                window.om5678_1234.reset();
8            }
9        });
10    }
11    componentWillUnmount() {
12        this.unlisten();
13    }
14    render() {
15        return (
16             
17 
18<div>{/* Your routes defined here. */}</div>
19 
20 
21        )
22    }
23}
EmberJS
1// Using Ember.js.
2import Route from '@ember/routing/route';
3export default Route.extend({
4    beforeModel(transition) {
5        if (window.om5678_1234) {
6            window.om5678_1234.reset();
7        }
8    }
9});
AngularJS
1// Using AngularJS.
2var myApp = angular.module('myApp', []);
3myApp.run(function($rootScope) {
4    $rootScope.$on("$locationChangeStart"function(event, next, current) {
5        if (window.om5678_1234) {
6            window.om5678_1234.reset();
7        }
8    });
9});

Troubleshooting

Where do I find my account ID and user ID?

These are readily accessible in the OptinMonster embed code.

You can find your embed code in the Publish screen of the campaign builder, then look for the data-account and data-user attributes.

OptinMonster account ID and user ID

StaticImage

  import React , { useEffect , useRef } from "react" import { StaticImage } from "gatsby-plugin-image" impor...