Saturday, November 10, 2018

Debounce and throttle function calls in JavaScript


Overview


Looking at debouncing and throttling function calls in JavaScript.

My source code on StackBlitz.com.

Because I am using global variables to keep track of the state, the function debounce() and throttle()
do  not support debouncing and throttling multiple function at the same time.
  • Throttling and Debouncing in JavaScript blog post by Jhey Tompkins
    • Which contains slightly more complicated version of throttle() function than mine.
  • A visual demo by nimius.net : Demo.

Html





JavaScript

  


    let _inThrottleIgnoredCount = 0;
    let _inThrottle = false;

    function throttle(func, limit = 100) {

        return function() {

            const args = arguments;
            const context = this;
            
            if (_inThrottle) {

                // Do not allow the call, just count the number of ignored call
                _inThrottleIgnoredCount += 1;
            }
            else {

                _inThrottle = true; // Do not allow any more call
                _inThrottleIgnoredCount = 0;
                func.apply(context, args); // Make the first call               
                // Set timer for the period for which we will not allow calls
                setTimeout(function () {

                    _inThrottle = false; // Allow call again
                    if(_inThrottleIgnoredCount > 0) { 
                      // If at least one call came during the period for 
                      // which we were not supposed to accept call, then
                      // let's execute the function one last time
                      _inThrottleIgnoredCount = 0;
                      func.apply(context, args); // Call one last time
                    }
                }, limit);
            }
        }
    }
    
    let _inDebounce = null;

    function debounce(func, delay = 100)  {

        return function() {

            const context = this;
            const args = arguments;
            if(_inDebounce !== null) {

                clearTimeout(_inDebounce); // Cancel pending call
                console.log(`Cancel call`);
            }            
            _inDebounce = setTimeout(() => { 

                _inDebounce = null;
                func.apply(context, args);
            }, delay);
        }
    }

    function doSomething() {
        console.log('doSomething');
    } 

Wednesday, October 24, 2018

How to create a 2 ways conversation between a web app and smart phone via SMS

Overview

May be you received these appointment confirmation via SMS where you have to answer C, to confirm. I have been playing for years with the Twilio API to send text message, but I wanted to build a 2 way conversations, that is to say
  1. From a web app client a person can send a SMS text to my iPhone
  2. I receive the text and from my iPhone I can answer the text with another text. The answer is then sent back in real time to the web app.

Applications

In these 2 screen shots, you can see that 
  1. A user went to the address ftorres.azurewebsites.net/sms, then enter the text 'How are you?' and press the Send button. I received the message as an SMS text on my iPhone.
  2. I answered back with the message 'Ok and you' which was received right away by the web app running in the browser.



Technical Implementation

A few words about the Twilio SMS api

When you want to send SMS with the Twilio API, you first need to buy a phone number, which cost $1 per month. This phone number allow you to
  1. When you send a SMS text programmatically, the SMS text for the receiver comes from this phone number.
  2. When you answer the text, the answer is sent to this phone number, which does nothing. But you can setup a web hook associate with this phone number to be called when it received a text. In other words when somebody send a SMS text this phone number, a custom REST API call is made and the custom API can do something with the source phone number and text message itself.

Sending the SMS text

  1. From the web app, when the Send button is clicked, the app execute the following REST call
    • https://xxxxxx.azurewebsites.net/api/sms/19787606031/How%20are%20you%3F
  2. In the Azure cloud at the address https://xxxxxx.azurewebsites.net/api/sms is an Azure Function written in C# that will use the Twilio API to send the SMS text (source method SendSms in the file AzureFunctions.SMS.API.cs).

Handling the answer


When I answer to the first text message, my answer and plenty of other information are sent the Twilio phone number I bought, the phone number is associated with a web hook configured with the following URL
  • https://xxxxxx.azurewebsites.net/api/sms/receive
The REST API is written in C# and running in another Azure Function (source method ReceiveSms in the file AzureFunctions.SMS.API.cs).

What the ReceiveSms method does is, it take all the name/value coming from Twilio (including the variable body which contain the text of the answer), serialized then into a JSON object and  publish the JSON string into an MQTT channel.

My Web App is listening to this MQTT channel and when it received a message, this mean that I sent an asnwer to the person behind the browser. The Web App parse the JSON, extract and display the content of the property Body.

List of technologies

Front end:REACT
Back end:Azure Functions written in C#, implementing a REST API. I developed the Azure Functions with Visual Studio (rather then from the cloud editor), ran and debug locally, then publish in Azure.
SMS Provider:Twilio
Real time communication:MQTT (broker www.CloudMQTT.com)

Multi Users Support

In the current state of the code, I cannot support having conversation with multiple users.
One thing I could do to support it is to prefix all the text message with a [Web-App-Id] text-message.

The Web-App-Id, can just be a unique random id, which would also be used as the MQTT client id. Therefore when each web apps running different browser instances receive an answer, they client could  determine is the answer is addressed to itself.

The annoying thing with this solution is that I would have to prefix my answer with [Web-App-Id],
to define the destination user, and I am not very good with iPhone keyboard.

Thursday, October 11, 2018

Debugging Jest unit tests in vsCode


How to configure vsCode to debug Jest unit tests?
  • vsCode Debugging See documentation link to configure vcCode to debug Jest unit tests
    • Regular breakpoint set using F9, do not work correctly
    • Breakpoints set using the key word debugger; are working correctly
  • File .vscode\launch.json example

{
 // Use IntelliSense to learn about possible attributes.
 // Hover to view descriptions of existing attributes.
 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
 "version": "0.2.0",
 "configurations": [
  {
   "type": "node",
   "request": "launch",
   "name": "Jest All",
   "program": "${workspaceFolder}/node_modules/.bin/jest",
   "args": ["--runInBand"],
   "console": "integratedTerminal",
   "internalConsoleOptions": "neverOpen",
   "windows": {
     "program": "${workspaceFolder}/node_modules/jest/bin/jest",
   }
  },
  {
   "type": "node",
   "request": "launch",
   "name": "Jest Current File",
   "program": "${workspaceFolder}/node_modules/.bin/jest",
   "args": ["${relativeFile}"],
   "console": "integratedTerminal",
   "internalConsoleOptions": "neverOpen",
   "windows": {
     "program": "${workspaceFolder}/node_modules/jest/bin/jest",
   }
  }
  
 ]
}

Sunday, October 7, 2018

Configuring MQTT JavaScript client for cloudmqtt.com

Overview

I had to struggle to make my MQTT Javascript code to work in a browser.  So here it is.
  • I am using the provider free plan from CloudMqtt.com
  1. Create a MQTT broker using the free plan 
  2. I used the Websockets Port 
  3. The url must be formatted this way: 'wss://m15.cloudmqtt.com'
  4. In the connection options, useSSL must be true
this._options = {
    port: webSocketPort, // Required for WebSocket
    useSSL: true,        // Required for WebSocket
    host: mqttUrl,
    clientId,
    username,
    password,
    keepalive: 60,
    reconnectPeriod: 1000,
    protocolId: 'MQIsdp',
    protocolVersion: 3,
    clean: true,
    encoding: 'utf8'
};

this._client = mqtt.connect(this._options.host, this._options);

Source code

Here the full source code for JavaScript and C#. The Javascript code was testing on
Chrome Windows and iOS, Edge and IE11.

All project MQTTManager on Github

Friday, September 28, 2018

Testing Javascript Promise With Jest

Overview

Jest offers the function expect() in combination with the properties resolves or rejects to test a function that return a Promise. This is just a reminder.

Link: An Async Example

describe('Testing promise with jest', () => {

 const buildAsyncFunction = function(promiseMustSucceed, result) {
  return (url) =>
   new Promise((resolve, reject) => {
    if(promiseMustSucceed)
     resolve(result);
    else
     reject(result);
   });
 };

 const errorResult = "error";
 const okResult    = "ok";
 const testUrl     = "http://foo";

 it('Async function should succeed', () => {

  const f = buildAsyncFunction(true, okResult);
  expect( f(testUrl) ).resolves.toEqual(okResult);
 });

 it('`Async function should failed', () => {

  const f = buildAsyncFunction(false, errorResult);
  expect( f(testUrl) ).rejects.toEqual(errorResult);
 });

 it('Async function should failed, but promise returned by catch() should succeed', () => {
  
  const func0 = buildAsyncFunction(false, errorResult);
  const promise0 = func0(testUrl);

  expect( promise0 ).rejects.toEqual(errorResult);     

  const ff = promise0
     .then(() => { throw Error('then() block unexpectedly called')})
     .catch((error) => { 
      console.log(`function f() failed error:${error}`); 
      expect(error).toEqual(errorResult);
      return okResult; 
     });

  expect(ff).resolves.toEqual(okResult);
 });
}); 

Tuesday, August 21, 2018

Favorites C# 6 and 7 features

C# Version Reference 

Function returning multiple values via tuple


        
static (string Alpha, string Beta) GetLetters () {
    return ("A", "B");
}
static void Main(string[] args) {
    Console.WriteLine(GetLetters());         
}

Result

(A, B)

Tracing function and parameter names


        
static void MyFunction(string myVariable) {
    Console.WriteLine($"  function: {nameof(MyFunction)}, variable: {nameof(myVariable)} = {myVariable} ");
}
static void Main(string[] args) {
    MyFunction("Fred");
}

Result

 function: MyFunction, variable: myVariable = Fred

Null-conditional operators


        
class Person {
    public string FirstName { get; set;}
}
static void HandleNull(Person p)
{
    var firstName = p?.FirstName; // return null if p or p.FirstName is null
    Console.WriteLine(firstName);
}
static void Main(string[] args) {
    HandleNull(new Person { FirstName = "Fred" });
    HandleNull(null);
}

Result

Fred

Property Initializer


        
   public static int BirthYear { get; set; } = 1974;
   public static int BirthYear2 { get; } = 1974;

Out Variables


        
if (int.TryParse(input, out int result))
    WriteLine(result);
else
    WriteLine("Could not parse input");

Local Functions


        
public static int Add(string op, int i1, int i2)
{
    switch(op)
    {
        case "add": return add(i1, i2);
        case "sub": return sub(i1, i2);
        default: throw new InvalidOperationException();
    }
            
    int add(int a, int b)
    {
        return a + b;
    }
    int sub(int a, int b)
    {
        return a - b;
    }
}

Numeric literal syntax improvements


        
static void Main(string[] args) {
    const int four = 0b0100; // Binary notation support
    const long hundredThousand = 100_000; // The digit separator can appear anywhere in the constant.
    Console.WriteLine($"four:{four}");
    Console.WriteLine($"hundredThousand:{hundredThousand}");
}

Result

4
100000

Friday, July 13, 2018

JavaScript Async/Await Reminder

Overview 

C# and JavaScript async/await provide the same feature dealing with asynchronous calls.
But the details are not the same.

Here is an article that talk about it
Comparing asynchronous patterns between C# and JavaScript

Code Sample

Here is a sample in NodeJs v 9.2, that show case why async/await is cleaner than nested Promises.
But it is important to understand what really happen behind the scene. See my comments.
/*
    Code sample based from 
        JavaScript ES 2017: Learn Async/Await by Example
        Brandon Morelli
        https://codeburst.io/javascript-es-2017-learn-async-await-by-example-48acc58bad65
*/

/* Nested asynchronous function with Promises */

function doubleAfter2Seconds(x) {
    return new Promise(resolve => {
        setTimeout(() => { resolve(x * 2); }, 1000);
    });
}
    
function addPromise(x){
    return new Promise(resolve => {
        doubleAfter2Seconds(10).then((a) => {
            doubleAfter2Seconds(20).then((b) => {
                doubleAfter2Seconds(30).then((c) => {
                    resolve(x + a + b + c);
                })
            })
        })
    });
}

console.log(`starting big async calculation with Promise`);

addPromise(5).then( (result) => {
    console.log(`big async calculation result:${result}`);
});


/* Nested asynchronous function with async/await */

console.log(`starting big async calculation async/await`);

/*
    The function addAsync does not return the result of the expression: x + a + b + c,
    as the code imply.

    Because the function is marked with the word async, the function
    really return a Promise.

    The line `return x + a + b + c;` will be executed if the promise succeed and the 
    value will be passed as the parameter of the method resolve().
*/
async function addAsync(x) {
    
    const a = await doubleAfter2Seconds(10); // Shortcut syntax to avoid to attach a 
                                             // then() and store the resolved value 
                                             // of the Promise in the variable a
    const b = await doubleAfter2Seconds(20);
    const c = await doubleAfter2Seconds(30);
    return x + a + b + c;
};

async function main() {

    // Long syntax to call an async method using a then().
    addAsync(5).then(
        (result) => {  /* result contains x + a + b + c */
            console.log(`big async calculation async/await result:${result}`);
        }
    );

    // Shortcut syntax to avoid to attach a then()
    const r = await addAsync(5);
    console.log(`big async calculation async/await r:${r}`);
}

main();