Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Wednesday, November 02, 2016

IntelliJ Ultimate Debugging JavaScript from the LightBend Activator/Play Framework

Symptom

You tried to debug a {java | type|}script in Chrome browser and it does not fire a breakpoint.

You have already made sure that JetBrain extension is installed in Chrome and configured right.

You've also added the JavaScript debugging configuration, and the web page launches (e.g., http://localhost:9000)

Fix

There is one more missing piece to this puzzle. You need to map the URL for where the scripts come from. This is clearly documented in the IntelliJ documentation, but nevertheless, it is not intuitive enough that it took a while for me to find out.

The key is that you need to type in the Remote URL in the Remote URL list. This is NOT OPTIONAL for Play users. If you are running the "out of the box" configuration of Play framework, and putting in your *.js under the "public" directory somewhere, then all you need to do is to just type in /assets (will become http://assets after you save it without any ill effect) where the public folder is in the list. Save it and any JavaScript or Typescript (with a map) can be debugged.

Enjoy!





Saturday, July 09, 2016

TypeScript: Avoid Using Lambda in CallBack, "this" is not Captured

Symptom:

You have created a TypeScript class, and assigned a callback to an object implemented in Lambda expression (or have been suggested by Reshaper or IntelliJ to convert it to a lambda expression).

See the example below and what the problem is about to become much more clear.

The Issue

The issue is that the Lambda captures "this" in a different way than the anonymous function (). This is actually clearly documented under the Arrow Functions section in the Mozilla MDN page.

But if you are like me it is much easier to understand by actually coding the situation.

The Explanation of The Example:

I have created a simple Main class in which a callback "whatIsThis()" can be externally installed after the class has been instantiated. Then by calling whatReallyIsThis(), it will in turn calls the installed whatIsThis(). This is a fairly typical scenario, I would say.

If you are not aware of all of the implications of this, you would (and I have) thought that the class member property "s" should be accessible from within the callback in all of the scenarios.

The ones that works are;

  • If the callback function is is a function() and not an arrow function like =>(). This will not work.
  • Also, you can try this yourself, any attempt to pass "this" as main like Apply, Call or Bind to the lambda function will have no effect. 
Lessons Learned

You should treat lambda as a whole new beast of function. It appears that they tried to fix the variable notion of "this" in lambda and it only captures "this" in the line of code where it was created. What throws you off is that you've learned about "this" with anonymous functions, and assumed it works the same. Be aware of this major difference!


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Main {
    constructor(public s: string) {}
    whatIsThis:  () => void;
    whatReallyIsThis() {
        this.whatIsThis();
    }
}

let main = new Main("works!");

console.log("Anonymouns func - this points to Main instance!");

main.whatIsThis = function() { 
    console.log("This " + this.s);
}

main.whatReallyIsThis(); // This works.

console.log("Using the Labmda - this does not work!");

main.whatIsThis = () => {
    console.log("This s is " + this.s);
}

main.whatReallyIsThis(); // This s is undefined

console.log("Finally, what is this is all about");
let that = main;
exports.s = "in Global scope"; // Yup, it's in the Global!
main.whatIsThis = =>()  {
    console.log"Thi(s s is " + this.s); 
    console.log("That.s " + that.s); 
}
main.whatReallyIsThis(); // This s is in Global scope, That.s works.


Thursday, July 03, 2014

Super Beginner Guide to AngularJS - Uncaught Object

OK, I will admit. I am just starting out learning AngularJS and already spent numerous hours where an experienced programmer won't step into. Well, just a few months from now, though, I won't be in that situation, nor I would remember the kind of traps I got into. So it's time to blog about them because if I ran into them, you would too.

What to Do If You Get Uncaught Object on Chrome Console

So your text book author said, "you can test in any browser you choose so long as it is Chrome." And you believed it, didn't you. You tried your first program, and you get the following message in the JavaScript console.

Uncaught object
  (anonymous function) angular.js:78
  (anonymous function) angular.js:1751
  ensure angular.js:1675
  module angular.js:1749
  (anonymous function) app.html:9

Unlike a debugging in C# or Java, it does not tell you where and what the issue is. Very frustrating. You even set a breakpoint where the issue was found and it says "missing ngLocale" module to that effect when you have not even plan to reference such a module in your code.

This turns out to be a current (as of July 2014) bug in Chrome. May be it has been fixed by the time you read this, but it goes to say that when debugging JavaScript it might be worthwhile trying another browser than just Chrome. Especially Firefox and IE are great choices as the JavaScript implementation is totally different from Chrome or Webkit based.

Error: [$injector:nomod] Module 'undefined' is not available! You have either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
http://errors.angularjs.org/1.3.0-beta.11/$injector/nomod?p0=undefined angular.js
Error: [$injector:nomod] Module 'mtSample' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
http://errors.angularjs.org/1.3.0-beta.11/$injector/nomod?p0=mtSample angular.js

Now at least here the debug console output will be more specific as to the nature of the problem. For above example, I have purposely eliminated a comma after "mtSample" from angular.module("mtSample" ["ngRoute"]).

Go Ahead, Try the IE too!

I know, I know, we are supposed to sit and code at Petes with our latest Mac Books and bash the IE ( I am writing this artile on my iMac by the way). But you will be surprised to know how much changes Microsoft has made to embrace the latest open source technology. You can even run Linux on Microsoft Azure now!

So, even on the IE, the message is clear! In fact, it is the cleanest and clearest of all in this specific example. So at least, let's give some hands to the Micrsoft folks. We should not lose a sight that as software engineers our task is to get our job done. I would use any tool I can lay my hands on.



A Side Note - Do Not Mix and Match Angular Libraries

I have accidentally mixed in additional Angular components (like routing package) from the latest into the rest which was in a pervious version. If you do this, you will run into a very similar issue. When in doubt, refresh the complete AngularJS library to the same perstine version.


... to be continued.

Friday, June 20, 2014

Avoiding CORS on localhost testing via Simple Node.js Proxy Server

What Is CORS Anyway?

Before I get deeper into this topic, I just want to tell you a bit about CORS. CORS an abbreviation of "Cross Origin Resource Sharing", and it is described in this Wikipedia Article.  To make a short summary of this issue, basically, what it means is that there is a security mechanism in just about every modern browser that prevent you to perform AJAX requests from a different server than where your original content came from.

For example, a typical tutorial lesson you get from books may require that you have a simple web server running on Node.js (really easy and cool) then a separate database server that's serving up JSON data (for example, via a Deployed service), you would do something like http://localhost:5000 for your web contents and then http://localhost:5500 for JSON data server. That triggers CORS.

Of course, if you ask most experts, they will say, the answer is easy. They will say just enable CORS on the server side. But it is not that simple. This is a blog about answers that experts do not know how to answer after all.

The reason I am writing this article is because I spent a couple of days to explore different ways of resolving this issue when I was writing some local development and testing environment to learn Angular.js

Because of a very specific way Angular.js performs the HTTP Get and Post the JSON data, you will find it difficult to get around CORS issue. There is even an extension in Chrome to allow CORS in Chrome but even with it, the POST part of the equation does not work for me. In my case, even if I (thought) modified the header to do;

Access-Control-Allow-Origin *
It still did not give me the result I wanted. I even read that on Firefox, a * is not even permitted, and that a specific host be specified. Pretty tricky if you want to test various browsers too! (*I even implemented a version of Microsft IIS site with web.config edited to allow CORS with no avail!)

It is also even worse when dealing with a localhost than any other hosts to get around CORS.

The Proxy Based Solution

In my situation, what ended up working the best is to completely avoid CORS altogether and make it look as if the database service is coming from the same server. And as a bonus of using Node.js it is quite easy to implement it.

It is basically the use of proxy-middleware (e.g. npm install proxy-middleware) that solved this. In this case, all of my test implementation files are stored under ./angularjs folder, so for example, http://localhost:5000/app.html will pull the file from ./angularjs/app.html

I then created a Deployd server at port 5500 (i.e., http://loclhost:5500) and I wanted my server to proxy all of these requests to that when an AJAX request is made to http://localhost:5000/db  So this means that when I was originally doing http://localhsot:5500/products to get the Products JSON data, I will request http://localhost:5000/db/products

var connect = require('connect')
    , url = require('url')
    , proxy = require('proxy-middleware')
    ;
var app = connect();
app.use(connect.logger('dev'));
app.use(connect.static('./angularjs'));
var proxyFunc = proxy(url.parse('http://localhost:5500'));
app.use('/db', proxyFunc);
app.listen(5000);

Stupid Side Note:

Actually, when I tried this the first time, it did not work, the POST failed, because I had some leftover modifications like this in my code

      app.config(['$httpProvider', function ($httpProvider) {
            //Reset headers to avoid OPTIONS request (aka preflight)
            $httpProvider.defaults.headers.common = {};
            $httpProvider.defaults.headers.post = {};
            $httpProvider.defaults.headers.put = {};
            $httpProvider.defaults.headers.patch = {};
        }]);

Be sure to back out any attempts you've done to fix the issue.  It should just work with a bare-bone POST call of Angular.js HTTP provider!




Wednesday, June 18, 2014

JavaScript for C# Programmers: Enumerating Properties

JavaScript Tips for C# Programmers


If you are from the C# (C or C++ too) world, mainly and you are planning to dive into more of "current" way of the JavaScript, you'd run into situations where "I can do this in C#" but why not in JavaScript, or what is going on here, it's not possible in C#.  Here are some notes I was taking as I was learning to apply to my situations. I think you are likely looking for the same answers.
Two Key Concepts in Understanding JavaScript Object

As I got up to speed with JavaScript coming from years of C# only programming, it dawned on me that there are two key concepts that really helps to un-do your C#, C++ minds.  The first one is the dynamic aspect of JavaScript, and also the rampant use of in-line function declarations.

It is Dynamic!


The most important thing to be aware of as a C# or C++ programmer is that the language is dynamic. This is very important in understanding the source codes.

For example, you'd be often confused reading lines of code and suddenly you run into a new property like .address in the example below,

myInfo.address = "1234 Main St.";

You could be wondering where is this .address come from? Where is it declared?

The key to understanding this is that the address member was just added now. There is no requirement in JavaScript to declare anything. You just build your object as you go. This approach is so different that even if you understood it first in a textbook, it will catch you off-guard. We are so fixated in the declaration part of it, it is hard to get rid of that thought. (Note there is a type of declaration, in JavaScript but I am not getting into that now.)

The easiest way to understand this in another way is that if you have used C# Dictionary<> then any JavaScript object is the equivalent of  MyObject.

Add("address", "1234 Main St."); In other words, JavaScript objects are nothing but key value pairs of name and objects.
Rampant Use of Function "Pointers or Delegates"

This is also another difficult part to undo your minds.

A JavaScript object can be a function and JavaScript programmer uses almost exclusively of this. And to confuse the matter even more, many of these functions are anonymous functions. And because you can do that a function are defined usually in a context of a function call! This is so widely used that without understanding this, you would not understand the most JavaScript code these days

var  myFunc = function(x) { return x = x + 1; }

is an example of anonymous function that's assigned to a pointer variable (so to speak) myFunc.

So later on the code you can do y = myFunc(2);

I don't like the term "anonymous" function as everything has to have some reference point. In fact, it does have a name in my example, which is myFunc. So whenever you hear about anonymous function, think of it as a function that's assigned to a variable which is like a function pointer in C or C++, or a delegate in C#.

This approach is used very commonly in callbacks.

myCallback(function(data) { ... });

This is same as

var myFunc = function(x) { return x = x + 1; };
myCallback(myFunc)

But it is done "in-line" in the calling parameters, which is especially odd looking with the C#, C++ mindset. But if you accept the fact that you can write a function as a parameter to a call, then it will start to sink in.

How To Access A Property That's All in Numeric String.


Given this is a very esoteric situation, it also illustrates a point that you can simply access any member of an object using the object['memberName'] notation.

Consider this situation (this is from Medical Imaging, DICOM protocol JSON obeject except that I have added 'patientName" to demonstrate the following example.)

theData={
'patientName' : { 'vr' : 'PN', 'Values' : ['Smith^John'] }

  '00100010' : { 'vr' : 'PN', 'Values' : ['Smith^John'] },

  '00100020  : { 'vr' : 'LO', 'Values' : ['123456'] }
}

The above is equivalent of the C# code like this.

public class myData
{
   public patientName = new DataElement();
   public  DataElement 00100010 = new DataElement();
   public  DataElement 00100020 = new DataElement();
};

Of course, this is not an acceptable syntax in C#, but it is in JavaScript it is possible to have something like this (and it is a part of the DICOM Web standard.

The patientName part is easy to get to just say something like myDataInstance.patientName, but if you try to do myData.00100010  it won't accept that (neither in C# nor in JavaScript actually).

Fortunate in JavaScript the objects are accessible as key value pairs and so it is possible to say theData['00100010'] to get to its content.


How About Finding All Its Properties?


You can iterate through

for (var prtop in heData) {
     var name = prop;
     var val = theData[prop];
        }

What is the === Stuff?

Remember, just this important point. JavaScript auto-converts types when doing an "==" comparison, so you can compare a string that just contains digits against an actual number and come out to be equal. === prevents that from happening.

To be continued...