codefoster | All posts tagged 'js'
Jeremy Foster
@codefoster

7 Reasons I Still Love JavaScript

by Jeremy Foster 27. December 2012 17:15

For many reasons, I still love developing Windows 8 apps using HTML, CSS, and JavaScript. I have extensive C# experience and always want to be able to say "I'm a C# developer", but I'd like to add that "I'm a JavaScript developer" as well. Some months ago I was a little pained to make even a short term commitment to write more JavaScript than C#. It felt a little like when I was learning French and found myself hesitant to start trying to think in French as if I would lose my English. Of course, that won't happen, and we shouldn't be afraid even of immersing ourselves in other languages. In fact, I'm a big advocate of the polyglot theory of intentionally moving into other languages spaces to expand our own scope, our value, and our perspective.

Becomes a way of thinking

I'm sure most development languages become a "way of thinking," but I think JavaScript does even more so because it's so dynamic and so light.

It's the language of the web

Mashups are a breeze when you're ingesting HTML and JSON data into and app that's made with HTML and JavaScript. The WinJS.xhr() method can make web requests with a request type of "document" and then immediately act on the results just like it would any other in-app content. Blob images can be consumed and repurposed. JavaScript objects can be created instantly out of JSON data. Yada yada yada. It's very convenient.

CSS selection of elements is great

Selectors are one huge strengths of the HTML/CSS that take advantage of the fact that HTML markup goes all the way to the client as XML-like syntax. Even on the client (at run-time) CSS can select very specific portions of the UI in order to affect it with styles or layout. JavaScript can take advantage of selectors too (using document.querySelector and .querySelectorAll) and that allows our logic to act on very specific portions of the UI.

One with the masses

There are a LOT of people writing JavaScript. A StackOverflow search on the [javascript] tag returns 300k+ questions on the matter (actually [c#] returns almost 400k!). It's good to have camaraderie in writing code. It's good to have employers looking for your skillset. It's good to have others asking questions on StackOverflow that you can benefit from. It's good to be one with the masses.

Standards driven

JavaScript is broadly adopted and is broadly and inherently appealing because it's based on web standards. The ECMAScript standard that is JavaScript, along with CSS and HTML, are governed by the World Wide Web Consortium (W3C) and that makes developers feel good. It's very democratic and very social and has very high likelihood of moving forward and moving in good directions.

Don't reinvent the wheel

There are a lot of JavaScript libraries out there. A lot. If you want to track faces or get fancy with date calculation or recognize touch gestures or implement IoC or pub/sub or manage Entity Framework data or edit images or any of a plethora of other things, there's a JavaScript library waiting for you.

A full stack of script

When you write C#, you don't usually just write C#. We find the client/server model everywhere and you don't send server code to the client, but you can send script. Whether you're writing an ASP.NET app or a client app, these days it seems you're inevitably going to be interacting with some HTML or even some JSON somewhere… whether you're using REST web services or scraping HTML screens. Having JavaScript on both the server end and the client end just tends to make you smile.

I like exploring languages. I am a veteran of VB. Like I have said, I'm a huge fan of C#. I have huge respect for C++ (though I haven't knocked on that door since college). I am exploring Erlang. Nevertheless, today I am having a blast writing JavaScript, and if you're writing JavaScript, I don't think you'll be hurting for work anytime soon!

Happy coding!

Tags: , , , , , , , , , , , , , , ,

CSS | HTML | JavaScript | Windows 8

Unintentionally Open Source?

by Jeremy Foster 11. December 2012 12:42

I saw this tweet and decided to respond.

The technical answer is YES. You can access the source code for Windows Store apps written in HTML/JavaScript. But there are a few reasons that you should forego panic.

First, this is no surprise. App packaging and distribution has a ton of design and testing behind it. The designers knew exactly what was going to the client and exactly how much effort it takes to discover it. Developers are responsible for their own obfuscation strategy. If Microsoft created their own, it would just get pwned in a couple weeks and then it would be a senseless inclusion in the product. It's better for obfuscation to be out of band with the Windows product and for it to be contributed by third parties.

Next, the way it works with HTML/JavaScript apps is actually similar to many other language stacks. JavaScript is clear text and translated script so it's very easy to look for a .js file and read it. Managed languages such as .NET languages are only logistically more difficult to reverse engineer and capture the source from.

Next, the source code is available on the client, but the package is tamper proof. If a hacker finds it and changes one of the .js files so that the script now does something it wasn't intended to do (such as validate that an in-app purchase has been paid for or that the app is not in trial mode), then Windows will not allow that package to execute.

Finally, the bottom line is that you should never trust code on a client. It doesn't matter the language, the platform, or even the obfuscation technique. It can and eventually will be hacked. You should consider how sensitive your intellectual property is and protect accordingly. If you have very valuable business logic that would hurt you or your company if it's taken then I wouldn't even put that logic into the client app. I would put it in the cloud and make it available through service calls. That's a better architecture for a lot of other reasons as well. If you are a hobby app developer and you wrote a silly app, I wouldn't worry about it. It's a very small portion of the population that's going to try to take your code. The chances that your stolen code is going to turn into much added value for them is low and the chances that their efforts with it are going to hurt your business is even lower.

Tags: , , , , , , , , , , ,

JavaScript | Windows 8

MCSD HTML5 Exam Offer

by Jeremy Foster 9. November 2012 21:39

It's was a big day in Building 33 as 100 or so people gathered to write Windows 8 apps, compete for prizes, and hopefully learn a little something along the way. One of the things attendees learned was that Microsoft Learning (MSL) is really rockin' the Microsoft certifications lately. Paul Lee joined us at the hackathon to talk about the state of Microsoft certifications. They have tracks that based on software solutions and the technologies a developer would use to create them.

The one I'm excited about is the MCSD: Windows Store Apps - HTML5. Which you can earn if you take the 70-480, 70-481, and 70-482 exams. And actually, the first of those exams is free (for now) if you go to http://www.register.prometric.com to schedule your exam and use HTMLJMP as your promo code. If you want help studying for 70-480 and 70-481, you can take a look at the JumpStart videos that Michael Palermo and I recorded at http://aka.ms/jump480 and http://aka.ms/jump481.

Attached are the slides that Paul presented.

HackathonOffer.pptx (429.56 kb)

Tags: , , , , , , , , , ,

Windows 8 | WinRT

Jump Start Your Brain

by Jeremy Foster 20. September 2012 17:40

My colleague Michael Palermo and I are scheduled to present two Jump Start video series on Channel 9. The first will cover basic HTML, CSS, and JavaScript development, and the second will cover those web technologies as they apply to creating Windows 8 apps.

You can get a lot more information about this content and register to attend by going to http://aka.ms/Win8Dev-JS.

Tags: , , , , , , , , , , , ,

CSS | HTML | JavaScript | Windows 8

A JavaScript Library for Everything

by Jeremy Foster 21. July 2012 08:29

Windows 8 is one of those environments that's just fun and expressive to develop in. So is JavaScript. The convergence of the two is just rockin'.

One of the great things about JavaScript is the enormous amount of code that other people have already written and put up on the web for your consumption. Do you want to wrap local storage (store.js), detect faces (liuliu), implement lightweight pubsub (minpubsub), or load JavaScript asynchronously (include.js)? You can do it by simply including a library in your Windows 8 project.

To find a library, you can always Bing (did you know that Bing results are preferred to Google 2:1 in blind taste tests?) for the functionality you need or you can try something here...

Tags: , , , , ,

JavaScript | Windows 8

Using Promises

by Jeremy Foster 22. June 2012 07:08

If you’re developing Windows 8 apps using JavaScript, then you’re likely familiar with the WinJS.Promise object. You can hardly get by without using one, because a lot of the API in WinJS and WinRT is asynchronous and for JavaScript apps they return a Promise.

I’m going to share with you what I have learned about promises so far in increasing order of sophistication.

Consuming a Promise

Everybody and their uncle is going to use this one. If you need to make a call to WinJS.xhr() for instance, you’re going to get a WinJS.Promise in return. They’re quite easy to deal with actually and you may already know this.

When you get a promise from a method, you simply hang a .then or a .done method off of it and provide a function that you want to run when the asynchronous method is complete.

WinJS.xhr({url:"http://someuri.com/service"})
    .done(function(xhr) {
        //do something here
    });

The call to .xhr comes back really quickly and you and your code go about your day even though the service hasn’t responded yet. Then when the service finally does come back to you, everything inside the done method runs. The promise that .xhr returns contains a payload as well. That’s why we’re able to declare our done function with function(xhr) and then access whatever it is the service returned.

So this is super handy for keeping our UI fast and fluid. But let’s move past merely consuming promises and get a bit more advanced.

Passing a Promise

You’ve seen how to consume a promise so that you can avoid a blocking call to a relatively long running or potentially long running method call. Sometimes you want to write a method yourself that calls an asynchronous method and you want to give your method caller the ability to call it asynchronously.

In this case, all you have to do is return the promise given to you by the asynchronous method you’re calling. So, for example, let’s wrap the example call to .xhr above with our own method call…

function myMethodAsync() {

    //may want to do some stuff here

    return WinJS.xhr({url:"http://someuri.com/service"})
        .done(function(xhr) {
            //do something here
        });
}

There we go. Now I can call myMethodAsync (and by the way, adding Async to the method name is a convention to indicate that it is an asynchronous method) like this…

myMethodAsync()
    .done(function(xhr) {
        // do something here
    });

And notice that I can still specify the xhr parameter for my done function and access the payload.

That’s how we pass along a promise from one asynchronous method to another. Sometimes, however, you need to start from scratch and create your own promise.

Creating a Promise

If I want to create my own method and allow callers to call it asynchronously then I need to return to them a promise. That’s simply the pattern in JavaScript.

Creating a promise is pretty easy, but you need to understand the concept because sometimes things can start to feel messy and it’s really helpful to understand what’s going on (not that I do entirely yet).

In Windows 8 JavaScript development we have the WinJS.Promise. You create it like this…

new WinJS.Promise(function(c,e,p) {
    //function body
});

The c, e, and p are parameters that are themselves functions. Within the function body, then, I can actually call c() when I want to complete the promise, call e() when I want to report an errant case, or call p() when I want to report progress.

Study this method I wrote that makes sure a file exists and if it doesn’t then it creates it…

function assureFileAsync() {
    return new WinJS.Promise(function (c, e, p) {
        if (fileExists("applicationData.json"))
            c();
        else
            appdata.roamingFolder.createFileAsync("applicationData.json")
                .then(function (file) {
                    return Windows.Storage.FileIO.writeTextAsync(
                        file, JSON.stringify(starterData)
                    );
                })
                .done(function () { c(); });
    });
}

There are a few things going on here, so let’s dissect.

First, I did use the Async suffix to indicate to the caller that this is going to be an asynchronous method. I create and return a new WinJS.Promise and the bulk of the logic here exists in the function declaration for that promise.

If a file called “applicationData.json” exists (fileExists is another function I wrote), then we don’t need to do anything and this promise should be considered complete, so we simply call c(). If we wanted our promise to carry a payload (like the xhr method does), then we could put that here by calling c(myResult). In this case, however, we don’t need that.

If the file does not exist, then we want to create it. Notice that this creation is itself an asynchronous call and in the .then there’s even another one. Finally, after we have made certain the file exists and contains my starterData, then we call the c() to indicate that this promise is complete.

There’s plenty more insinuated by this, but I’m going to leave it there for now in the interest of simplicity.

Saving a Promise

Now this trick I just figured out recently and it’s very handy.

Let’s say that in one part of my code I want to do something (call it Action A) that may take some time, and then in another place I want to do something else (call it Action B) but Action B should not occur until Action A has successfully completed.

I could let Action B call Action A asynchronously because then I could hang the .then or .done on that call. Sometimes, though, I don’t want Action B to be the initiator.

Let’s look at a more concrete example. This is the case where I ended up discovering this pattern.

When my application loads I want to load all of the data from file. When you user lands on the home page, I want to show the loaded data. Obviously I can’t show the user the data until it’s loaded, but I want to initiate the data load in the app’s activated event not in the home page.

So here’s what we do. We initiate the data load from the app’s activated event and save the resulting promise somewhere where it will be accessible to the home page. I just added it dynamically onto the WinJS.Application object (not sure if that’s recommended or not, but it works great :) Then from the home page, we simply access that object and hang a .done on it. Easy.

Here’s the data load call from my app activated event…

WinJS.Application.dataLoadedPromise = Data.initializeAsync();

…and here’s where I want to start work on my home page data, but only after the data is loaded…

var hubItemsList = new WinJS.Binding.List();
WinJS.Application.dataLoadedPromise.done(function () {
    getHubItemsAsync()
    ...

Now getHubItemsAsync (itself another asynchronous call, but that’s coincidental) will only get called once the dataLoadedPromise is complete.

Conclusion

There’s much more to promises that I didn’t include here - for brevity in part, but also because I haven’t discovered it yet, but keep an eye on this blog. As I turn over new leaves, I’ll post it here - I promise.

Tags: , , , , , , ,

JavaScript | Windows 8

How to do Semantic Zoom in an HTML/JS App

by Jeremy Foster 13. June 2012 10:17

Semantic Zoom is super easy, but even the easy things can use some conceptual explanation and examples to clarify them. Rest assured that once you see it, you’ll go “Ah! That won’t be a problem then.”

If you use XAML/C# to make your Metro apps, then you should check out Jerry Nixon's post on semantic zoom.

So, I’m going to be talking about Semantic Zoom. You know what that is right? It’s different from optical zoom. It’s a Windows 8 differentiator and it’s really helpful. It’s a way of zooming out of some information and making it easier to orient and easier to consume. Optical zoom just scales everything. Semantic zoom shows a different logical version of the same list.

Any given list in a Windows 8 screen may be 3 or 4 or 5 screens worth of horizontal information, right? Well, it’s not hard to pan that far, but it’s not always easy to really see what your scope is when it’s on 4 screens. When a user semantically zooms out, he is hoping to get oriented with your data. He is hoping to rise up so he can understand and/or so he can dive back in at just the right place.

I’m going to provide an example here. My example is a list of attractions in Kauai. Each has a category property - things like Flora, Scenery, Waterfall, etc. I will use these categories to group my list, but with the grouping and all of the content I want to show, the list is about 4 screens wide…

image

This might be a good scope of data for this view in my app, but at the same time it might be too much to expect a user to be able to consume in a glance. So, we implement semantic zoom. When the user pinch zooms, we want to show them something like this…

image

This is not very stylish, I know, but it serves to make the point. We want to indicate in much less horizontal space (and hopefully on a single screen) what our data contains. In this case, we’re showing the categories. We could get quite creative with what we show here. The concept is to logically expand our scope to orient the user.

Now when the user chooses the Waterfall tile, he’ll be semantically zoomed back in and will be taken directly to the waterfall section. The user can also zoom back in using a stretch zoom gesture (two fingers on the screen and then moved further apart).

Let’s move on to how to implement this. It’s by no means rocket science. Unless of course you’re building an app for… er… rocket science.

Start off with a blank Metro application. First thing you’re going to need is the data.

In your default.js file, add an onready function like this…

app.onready = function (args) {
    
};

And then inside of it add your data like this…

var attractions = [
    { name: "Fern Grotto", category: "Flora", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/98/super/fern_grotto-kauai-attraction.JPG", description: "Only accessible by boat or Kayak, the fern Grotto is located about two miles up Kauai’s Wailua River, the only navigable river in the State of Hawaii." },
    { name: "Hanalei Valley Lookout", category: "Scenery", location: "North", imageUrl: "http://www.kauai.com/photos/kauai/point/51/super/hanalei-valley-lookout-kauai-attractions-3.jpg", description: "The Hanalei Valley is an enchanted site charmed with the likes of countless waterfalls, rainbows, fields of taro and hidden treasures waiting to be explored." },
    { name: "Hanapepe Swinging Bridge", category: "Other", location: "West", imageUrl: "http://www.kauai.com/photos/kauai/point/93/super/843726541306971801.jpg", description: "Located in old town Hananpepe a Historical sight made up of an eclectic group of galleries and shops. Home to Friday night Art walk." },
    { name: "Kalalau Lookout", category: "Scenery", location: "West", imageUrl: "http://www.kauai.com/photos/kauai/point/94/super/3075381091306977440.jpg", description: "The Kalalau lookout stands at 4,00 feet above sea level and gives you a peek at a valley that as late as the 1920's still was the home to residents who farmed crops there. The only way into the valley is by foot along the Kalalau Trail or by boat." },
    { name: "Kauai Coastal Path", category: "Coastline", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/100/super/kauai-coastal-path-kauai-attractions.JPG", description: "Kauai Coastal Path is a scenic and and safe place to walk, run or bike while taking in the beautiful scenery of Kauai's East Side." },
    { name: "Keahua Arboretum", category: "Flora", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/95/super/keahua-arboretum-kauai-attractions-5.JPG", description: "The Keahua Arboretum is planted with native and introduced plants by the University of Hawaii and is used as an outdoor classroom to students and visitors. Cool off in the cold mountain spring water and enjoy lunch at one of the picnic sites." },
    { name: "Kilauea Lighthouse National Wildlife Preserve", category: "Coastline", location: "North", imageUrl: "http://www.kauai.com/photos/kauai/point/49/super/kilauea_lighthouse_national_wildlife_preserve-kauai-attraction.JPG", description: "Kilauea Point National Wildlife Refuge started in 1985 by the U.S. Fish and Wildlife Service is marked by its towering lighthouse. The ocean cliffs and tall grassy slopes of a dormant volcano provide a protective breeding ground for many Hawaiian seabirds" },
    { name: "Koloa Landing", category: "Coastline", location: "South", imageUrl: "http://www.kauai.com/photos/kauai/point/99/super/koloa-landing-kauai-attractions-2.jpg", description: "Once one of the largest deep water whaling ports in Hawaii, Koloa Landing is now a popular location for shore dives." },
    { name: "Lawai International Center", category: "Other", location: "South", imageUrl: "http://www.kauai.com/photos/kauai/point/110/super/lawai-international-center-kauai-attractions.JPG", description: "Lawai International Center and the 88 Shrines are located on the ancient site of Heiau where Hawaiians once came for healing." },
    { name: "Menehune Fishpond", category: "Other", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/48/super/menehune-fishpond-kauai-attractions.JPG", description: "Menehune Fish Pond is located just above the Nawiliwili Harbor. The Menuhune Fish Pond, Alekoko got it's name from the legend that a small race of people known as menehune built these ponds 1,000 years ago overnight." },
    { name: "Napali Coast", category: "Coastline", location: "North", imageUrl: "http://www.kauai.com/photos/kauai/point/82/super/napali-coast-kauai-attractions.jpg", description: "The Napali is a fifteen mile stretch of coastline starting on the north shore at Kee beach and ending on the west side at Polihale beach. This rugged coast will leave you breathless as you gaze upon the he razor sharp cliffs that rise sharply from sea to " },
    { name: "Opaekaa Falls", category: "Waterfall", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/88/super/opaekaa_falls-kauai-attraction.JPG", description: "Opaekaa Falls can be seen from the scenic lookout along Kuamoo Road in the Wailua Homesteads. " },
    { name: "Spouting Horn", category: "Coastline", location: "South", imageUrl: "http://www.kauai.com/photos/kauai/point/86/super/spouting-horn-kauai-attractions-1.JPG", description: "Spouting Horn Beach Park is a delightful lookout where you can watch a blowhole spout a plume of sea water into the air." },
    { name: "Tree Tunnel", category: "Flora", location: "South", imageUrl: "http://www.kauai.com/photos/kauai/point/91/super/tree-tunnel-kauai-attractions.JPG", description: "The beautiful canopy of eucalyptus trees line Maliuhi Road, the gateway to Kauai's sunny side and the towns of Koloa, and Poipu." },
    { name: "Wailua Falls", category: "Waterfall", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/50/super/wailua_falls-kauai-attraction.JPG", description: "This 140 foot waterfall appears on many postcards, print and media collections and was used as the opening scene for the 1970’s Television series Fantasy Island." },
    { name: "Waimea Canyon", category: "Other", location: "West", imageUrl: "http://www.kauai.com/photos/kauai/point/83/super/waimea-canyon-kauai-attractions-2.JPG", description: "Waimea Canyon State Park is the largest canyon in the Pacific and will undoubtedly capture your gaze, with its 10 mile long stretch at a mile wide and measuring more than 3,500 feet deep." },
    { name: "Wet and Dry Caves", category: "Other", location: "North", imageUrl: "http://www.kauai.com/photos/kauai/point/111/super/wet-and-dry-caves-kauai-attractions.jpg", description: "Waikanaloa & Waikapalae Wet Caves are located off the the main road in the Haena State Park and are easy to get to. The Waikanaloa Cave is not for swimming. The Waikapale cave is located a a little further up the road and involves a quick hike to the swim" },
];

And then you need to turn that simple JavaScript array into a Binding List so you can bind to it. Like this…

var attractionsList = new WinJS.Binding.List(attractions);

And then you group that list like this…

var attractionsListGrouped = attractionsList.createGrouped(
    function (i) { return i.category; }, //group key
    function (i) { return { category: i.category }; }  //group
);

And there’s that.

Now, let’s visit your HTML file (default.html).

You’ll need your actual ListView…

<div id="zoomedinlist" data-win-control="WinJS.UI.ListView"></div>

And you’ll also need a template and a header template…

<div id="headertemplate" data-win-control="WinJS.Binding.Template">
    <div data-win-bind="innerText:category"></div>
</div>
<div id="zoomedintemplate" data-win-control="WinJS.Binding.Template">
    <div>
        <img class="item-image" data-win-bind="src:imageUrl" />
        <div data-win-bind="innerText:name"></div>
    </div>
</div>

And then you need to bind the ListView to your data, so go back to your default.js file and after the var attractionsListGrouped statement, add this…

var zin = q("#zoomedinlist").winControl;
zin.itemDataSource = attractionsListGrouped.dataSource;
zin.groupDataSource = attractionsListGrouped.groups.dataSource;
zin.itemTemplate = q("#zoomedintemplate");
zin.groupHeaderTemplate = q("#headertemplate");

Now you should have a working list, and all we have to do is add the semantically zoomed out version and the semantic zoom control itself.

So, on the default.html page, add the semantic zoom control and the zoomedoutlist to the list you already have like this…

<div data-win-control="WinJS.UI.SemanticZoom">
    <div id="zoomedinlist" data-win-control="WinJS.UI.ListView"></div>
    <div id="zoomedoutlist" data-win-control="WinJS.UI.ListView"></div>
</div>

(note that last code should be pasted over the existing zoomedinlist since we already had that there)

Then, that zoomedoutlist needs some data binding, so we go back to the default.js and add this…

var zout = q("#zoomedoutlist").winControl;
zout.itemDataSource = attractionsListGrouped.groups.dataSource;
zout.itemTemplate = q("#zoomedouttemplate");

OKAY STOP. Let me explain what’s going on here. Quite simply, we’re just adding two different ListView controls with their own data bindings (that happen to be based on the same data, and then we are wrapping both of those up with the WinJS.UI.SemanticZoom control.

Keep in mind, that there are no constraints necessarily on what can comprise those two lists. You, the developer, are responsible for making sure that your semantic zoom control makes good sense for the user.

Now, please notice that the data source for the zoomed in list is a grouped list of attractions, while the data source for the zoomed out list is a list of groups. Thanks why we get the categories for our zoomed out tiles.

I added a couple of classes in the templates that I had you paste into your HTML, so if you add the following style rules to your default.css file, then that should make everything look sensible…

.item-image {
    width: 280px;
    height: 210px;
}

.sz-category {
    width: 200px;
    height: 200px;
    background-color: green;
    color: white;
    font-weight:bold;
    font-size: large;
    padding: 10px;
}

And that should do it. Leave a comment if this was helpful. Actually, leave a comment if it wasn’t helpful too. :)

Happy zooming.

Tags: , , , , , , , , , , , , , , , ,

CSS | HTML | JavaScript | Windows 8

Feed Subscribe