rc3.org

Strong opinions, weakly held

Tag: JavaScript (page 1 of 3)

But something else has happened over the past ten years; browsers got better. Their support for standards improved, and now there are evergreen browsers: automatically updating browsers, each version more capable and standards compliant than the last. With newer standards like HTML Imports, Object.observe, Promises, and HTML Templates I think it’s time to rethink the model of JS frameworks. There’s no need to invent yet another way to do something, just use HTML+CSS+JS.

Joe Gregorio argues that we should stop writing and adopting JavaScript frameworks and rely on the modern Web instead. This article is a great big picture view of the Web front-end as it exists today. If you do Web development, it’s a must-read.

Update: Read this excellent follow-up from Sam Ruby as well.

The near future of JavaScript

If you are a Web developer, you should check out Brendan Eich’s Strange Loop presentation on The State of JavaScript. JavaScript was supposed to be my 2011 skill of the year, but I really didn’t make any progress toward that goal and wound up learning other things instead. This year I’ve learned a ton of things, but not much JavaScript. In the meantime, JavaScript has become an even more essential skill for developers. As it turns out, I have managed to learn a fair amount of Scala and Hadoop since I wrote that post, and I’m learning Python right now as well. Maybe in 2013 I’ll get back to JavaScript.

Hash-Bang URLs and overuse of AJAX

Scott Gilbertson looks into the use of JavaScript in Gawker’s redesign:

The problem with Gawker’s redesign is that it uses JavaScript to load everything. That means that, not only is there no chance for the site to degrade gracefully in browsers that don’t have JavaScript enabled, the smallest JavaScript typo can crash the entire website.

I really don’t get this new trend (as Gilbertson notes, Gawker is following Twitter’s lead) toward sites that require JavaScript to load all the content on the pages. If a developer suggested such a scheme to me, I would be more inclined to fire them than to take their suggestion.

People were, at one time, hesitant to use AJAX to load all the content on their pages, because it made it difficult for search engines to index the content on those pages. Google offered a solution to that by way of hash bang URLs. And now, because Google allows it, it seems like developers are rushing headlong to adopt what sure looks to me like an anti-pattern.

I love AJAX and I think there’s a place for content that is loaded through AJAX but that should still be indexed by search engines. But generally speaking, if content should be indexed, then it should live at a static URL and be loaded through normal HTML rather than being loaded onto the page via AJAX.

Gilbertson’s source for his post is this lengthy explanation of why things went wrong for Gawker by Mike Davies.

What I wasn’t able to find is an argument in favor of building Web sites in this fashion — that is to say, loading everything via AJAX. Anyone have a pointer or want to make the case?

2011 Skill of the Year

I’ve set upon the idea of picking up a new skill this year. Over the past couple of years I’ve let my Ruby on Rails skills atrophy as I haven’t been working on any Rails applications professionally, and the Rails world changes too quickly to keep up with if you aren’t immersed in it every day. Instead I’ve been using a lot of Java, PHP, HTML, CSS, and SQL, with a dash of client-side JavaScript when needed. In 2011, it’s time to pick up something new or take a new look at something old. Here are the options I considered.

Ruby on Rails is something I already know, or at least knew, and I’m sure I could pick it back up quickly. However, I still don’t have a good Ruby on Rails project on the horizon, and so it would be just as much a pain to keep as it has been. I wouldn’t mind having a new Rails project to work on, but until one comes along, I’m going to leave it alone. I would consider working on my Ruby skills, but it’s hard to use Ruby for general purpose scripts at work because our servers all run Red Hat Enterprise Linux, which uses some old version of Ruby and is apparently impossible to upgrade. Ruby on Rails, I love you, but it’s a pass for 2011.

I am intrigued by big data projects. I’d love to dig into Hadoop or other tools that can be used to manipulate large data sets, but at the same time, I already work with some fairly big data sets at work and find that I can mine the data out of them that I need with SQL. In other words, while this area intrigues me, I don’t have any interesting problems to solve right now. Without that, it becomes tough to get motivated to really dig in and learn this stuff.

Another option is to learn a new (to me) programming language, like Clojure or Scala. Doing so would be great in terms of mental stimulation, but probably less great in terms of practical application. We’re not going to start using either of them at work this year, so I’d probably spend months learning one of them and then forget nearly everything I’d learned before I ever got to turn back to them for practical reasons.

Android or iOS are other options. Mobile development is huge right now, and I have a lot of ideas for apps I’d like to build. I could probably pick up Android development fairly easily since I already know Java. The only reason not to do it is that I am not a great user interface designer, and the best mobile apps are triumphs of interface design. I certainly have time to become a solid mobile developer, but without someone else’s design to implement, I think I’d just be unsatisfied with the results of my work. I may still try to pick up some mobile development skills, but they’re not going to be my primary focus this year.

The choice I settled on is JavaScript and Node.js. I already know JavaScript, but I wouldn’t consider myself a strong JavaScript programmer. I can generally solve the problems I’m asked to solve in JavaScript, but I find myself using a lot of libraries that there’s no way I could write on my own, and it’s easy to get lost in complex scripts. Not only is Node.js interesting in its own right, but learning about it gives a good chance to learn pure JavaScript as opposed to JavaScript simply as a way to manipulate Web pages. I’ve said before that HTML, CSS, JavaScript, and SQL are the most transferrable skills for Web developers. JavaScript is the weakest of those skills for me, and I need to get better at it. That’s the plan for 2011.

How The Wilderness Downtown was made

Ricardo “Mr.doob” Cabello headed up the programming behind the amazing Arcade Fire interactive video The Wilderness Downtown, which was built using HTML5 and JavaScript. He’s documented how the video was made on his blog, and it’s worth reading for JavaScript hackers. A few years ago, I worked on a project that replaced a Flash-based promotional application for a health insurance company with a version built using JavaScript and HTML. The end result wound up being pretty decent, but my main impression at the end was that it was a ton of work for results that fell short of the original Flash application in terms of dynamic impact. I attribute their more impressive results to the fact that they didn’t have to deal with Internet Explorer 6. Hat tip, Webmonkey.

Defending view source

Dojo developer Alex Russell continues to look out for view source:

If HTML is just another bytecode container and rendering runtime, we’ll have lost part of what made the web special, and I’m afraid HTML will lose to other formats by willingly giving up its differentiators and playing on their turf. Who knows, it might turn out well, but it’s not a vision of the web that holds my interest.

I linked to his previous warning on this subject back in January.

Building a new service from scratch, followup

About a month ago I asked what people would use to build a new Web service from scratch, without providing any real details on what the application would do. People seemed to all agree that basing the service on JSON was the best way to go, and that’s the route I took, so I thought I’d write it up.

In this case, I have a PHP front end talking to a Java back end that uses Spring and Hibernate. The application in question is the administrative console for a test harness for a SOAP Web service. We use a third party SOAP service and needed the ability to provide responses that are guaranteed to always be the same for the purpose of creating tests. So my test harness stands in for the third party service, requiring only a URL change, and returns the data managed via the client application to which my question referred.

The application itself is very simple — it’s a single table with a lookup mechanism. The client enables users to find and edit individual records from the table. I needed four basic operations:

  • Search for records
  • Retrieve a single record
  • Update a record
  • Create a record
  • Delete a record

The Server

This is a Java application that uses Spring and Spring MVC. I use Spring’s Web Services support for the SOAP stuff, but it wasn’t worth it to bother with that for the administrative client. So instead I mapped every URL ending in .json to a Spring DispatcherServlet. Like all sensible Java developers who’ve worked in Rails, I hate configuration in general and XML configuration files in particular. So I used Spring’s ControllerClassNameHandlerMapping, which extracts the path from the URL and maps it to a Spring controller.

So a path like /myapp/responses/search.json calls the search() method in the ResponsesController class. Simple.

I won’t go into the boring details of my implementation, other than to talk about how I’m passing the messages back and forth. The client uses standard form submission (name and value pairs) to submit the data, and expects to get JSON back. So in the case of search, I extract the field name and query value, go to the database and run a query to retrieve the records in question, and then package them up and encode them using JSON to be sent back to the client.

The JSON encoding is handled by Google’s GSON library, and it’s ridiculously simple. It accepts a plain Java object, and serializes it and all of its children using reflection. Any properties that are null are omitted. So for my application, I created a wrapper object that was well-suited to being encoded using GSON. It includes a hash for error messages, a property for a single response object, and a collection of response objects for search results.

Then I created a view for Spring called SimpleGsonView, which accepts a wrapper (or any object), encodes it using GSON, and then sends the results to the client. Here’s the whole thing:

@Override
protected void renderMergedOutputModel(Map aMap, 
    HttpServletRequest aRequest, 
    HttpServletResponse aResponse) throws Exception
{
    Object wrapper = aMap.get("wrapper");
    Gson gson = new Gson();
    aResponse.setContentType("application/json");
    ServletOutputStream out = aResponse.getOutputStream();
    out.print(gson.toJson(wrapper).replaceAll("\\\\n", ""));
    logger.debug(gson.toJson(wrapper));
    out.flush();
}

One thing you may notice is that I do a search and replace on the JSON. It removes all occurrences of \n from the encoded data. That’s a hack to get around a client side bug that I got tired of trying to fix. I’ll talk about that later.

So for this application, to add new functionality, I just add a new method to my controller, process the input parameters and put the correct results in the wrapper, and then pass that to the view I created. Very simple. I added an autocomplete feature to the search page, and this is all I had to do to add support for it on the back end:

public ModelAndView complete(HttpServletRequest aRequest, 
    HttpServletResponse aResponse)
{
    String searchField = aRequest.getParameter("field");
    String searchQuery = aRequest.getParameter("query");

    List<String> results = Collections.emptyList();

    if (searchField.equals(FIRST_NAME))
    {
        results = getFirstNameCompletions(searchQuery);
    }
    else if (searchField.equals(LAST_NAME))
    {
        results = getLastNameCompletions(searchQuery);
    }
    else if (searchField.equals(KEY))
    {
        results = getKeyCompletions(searchQuery);
    }
    else if (searchField.equals(ZIP))
    {
        results = getZipCompletions(searchQuery);
    }

    return new ModelAndView(new SimpleGsonView(), "wrapper", 
        results);
}

The methods to retrieve the data are in another class, but I removed the reference to it for simplicity.

So that’s the server piece. I could have done more to make it RESTful but since the service is just for me, I went with the simplest possible approach.

The Client

For legacy reasons the client is a PHP application, and I decided to use jQuery and a little PHP to implement the client features. Here’s how each operation is implemented:

Search: The search feature is pure jQuery. The home page for the client has a search form on it with a pulldown of fields that can be searched and a text box for the search terms. I used the autocomplete feature from jQuery UI to make the search form a bit friendlier. I catch the submission of the search from (or the selection of an item in the list provided by autocomplete) and submit the results to the server using jQuery’s getJSON() method. Then I create a table on the page with the search results in it.

Retrieve a single record: This is the only place I used PHP to connect to the server. I decided that I wanted each item to have its own URL, and although I could have written the code to pull the key for the item in the URL, fetch it, and build the page in JavaScript, I opted to use PHP instead. To do so, I grabbed a copy of the Services_JSON library and included that in my app. PHP supports JSON natively starting with version 5.2, but my server is running PHP 5.1. I chose Services_JSON because it’s a single file. So when you go to the edit or show page, I use PHP to fetch the JSON for the key in the URL from the server and put it on the detail page or in the edit form. This is where the bug comes in. My service returns XML documents (encoded as a value in a JSON hash), and sometimes Services_JSON won’t decode the data properly. When I started stripping \n from the XML, it worked, so I went with it.

Create a record: This form uses jQuery’s post() method to submit the contents of the form to the server. If the request returns a successful result, it redirects the user to the detail page for the new item. If it doesn’t, it displays the errors included in the result.

Update a record: This form works just like the create form.

Delete a record: This is the simplest operation of all. It submits the key to be deleted, and the server simply returns true or false.

Upshot

This was just about the easiest implementation of an application and accompanying Web service I’ve ever done, in spite of the fact that I’m a pretty terrible JavaScript developer. The server side was much easier to implement than I’d anticipated, it took less code in Java than it would have in PHP, and not much more code than it would have taken in Ruby. This is the application that really convinced me that there’s essentially no development overhead involved with using AJAX rather than traditional server-side request processing when building Web applications, at least if you bring libraries like jQuery and GSON to the party to make things easier.

Daring Fireball on PastryKit

John Gruber has a piece on JavaScript framework Apple has developed for the iPhone: PastryKit. It’s interesting to see how close Apple is getting to providing the “native experience” in a Web application. It’s a lot closer than most people would have thought possible, I think.

Storing data for Google Maps

I hinted at this in my link post, but I thought I’d write up the whole thing in hopes of discussing it. I have a page that will include a Google Map with markers for a number of locations (potentially a large number of markers). For an explanation of how to add markers to a Google Map, check out this page.

So the question is: how do you get the address data from my database to Google Maps?

The process is to geocode the address and then apply the marker to the map. There’s a simple example at that link.

Here are some possible approaches:

  1. Write some code (PHP in this case) that emits the JavaScript used to geocode the addresses and put the markers on the map. Unfortunately then you have a mixture of JavaScript and PHP code that looks a lot like JavaScript on your page.
  2. Print out a JavaScript data structure that contains all the information for the markers and then iterate over that data structure in JavaScript.
  3. Put the map data in hidden elements on the page where it can be extracted using JavaScript. The downside is you have hidden elements on your page. The upside is that your PHP is completely separated from your JavaScript.
  4. Create a service that returns a JSON data structure of the marker information that can be called using XmlHttpRequest and call that from the page. That offers a clean separation of the JavaScript from the PHP but unfortunately could add latency to the page.

I’ve done some searching to find out how people handle this problem, but haven’t seen any good answers yet. Any ideas?

Links for August 25

  • Glenn Greenwald on what all Americans should know about the 2004 CIA Inspector General’s report that was released on Monday.
  • Alex Tabarrok (the more doctrinaire libertarian half of the team at Marginal Revolution) explains why you must have a public option if health care reform will include an individual mandate. Further proof that I was completely wrong in arguing that the public option is not necessary.
  • Spencer Ackerman explains the insidiousness of torture — once you’ve embarked on a program of torture, the logical response to not getting the information you expect is to order more torture.
  • If you’re trying to embed Google Maps in your Web site and want to start with a centered map of the United States, Lebanon, Kansas is the spot.
  • Today I was trying to come up with good ways to avoid mixing JavaScript code with PHP code. Here’s a Stack Overflow question on the topic. I almost wonder whether using AJAX is better than writing PHP that emits JavaScript.
Older posts

© 2024 rc3.org

Theme by Anders NorenUp ↑