Category Archives: Uncategorized

JSON Parsing – Unexpected Token

This is a quick note because I just had this issue parsing JSON that was returned to me from the server. I was attempting to use JSON.parse, jQuery.parseJSON, and eval()… but i kept getting a range of errors depending how i attempted to manipulate it:

  • Unexpected Token {
  • Unexpected Token :
  • Unexpected Token ILLEGAL

And one or two more.  I searched a bunch of pages and it seems other people have this as well.  Also, my JSON validated with this validator.

Anyway, the solution for me, and others it seems, was to replace newline characters.  I was able to dig into the error a little bit using Chrome’s developer tools console to try to get the string to parse. The error allowed for expanding and hidden deeper in the stack trace was an error that suggested there were newline characters.  I also saw another post where someone had strings ending with the C string terminator ‘\0’

So, if you’re having this issue, try to get the JSON to parse in the console and see if there is some random character put in there that needs to be replaced.

success: function(response) {
   // REPONSE data has newlines!!  replace or it won't parse!
   var data = $.parseJSON(response.replace(/\n/g,"")); 
   // or use JSON.parse(...) if you're not using jquery and have a modern browser)
   // or... go download json2.js and use that.
   ...
                    
}

One other note… i’m using jsonp through jQuery so the data is returned as a string. Otherwise jQuery would have taken care of parsing it for me.

Share

jQuery ready function with holdReady

I used this the other day in GWT, prior to backing it out and placing style classes in better places so i could use straight CSS targeting.  But, I thought it could be useful and it uses the new jQuery.holdReady function so here it is.

My goal was this: In order to get the correct horizontal scrollbar in a GWT app, I had to target the div right ABOVE the root div placed in my Root View (which contains the structural layout of my page). I used jQuery to target that div, but they went back and placed a styleclass in the RootLayoutPanel widget instead so that i could target this more cleanly (within GWT) with CSS’s :nth-of-type / :nth-child selector.  I found the exact DIV that i needed to target by placing overflow-x: auto !important on all the parent divs until it worked ‘correctly.’

The ‘pageScrolling’ style class is defined with only overflow-x: auto !important

/* Startup functions */

/*
* First, place a hold on the document ready function... GWT loads more stuff
* after the DOM loads, and we need to add a little extra delay to account for that.
*
* By using document ready and hold ready together, i am able to make sure that the
* startup function runs after the page is completely ready.
*/
jQuery.holdReady(true);

// Set up the on-DOM-ready function
jQuery(function($) {
  // Find the DIV that should handle scrolling for the "body" and mark it
  $('.myRootPanel').parent().addClass('pageScrolling');
});

/*
* GWT needs to create its structure, which happens after DOM loads??
* Therefore, hold the document READY function until an expected element
* is detected
*
* (ps.. This holds ALL jQuery ready functions anywhere the system... if there are any)
*/
var waitForPageToLoad = function() {
  if (jQuery('.myRootPanel').size() > 0) {
    // it exists now.. trigger the ready function
    jQuery.holdReady(false);
  } else {
    // Doesn't exist yet.. wait some randomly selected time period.
    setTimeout( waitForPageToLoad, 200 );
  }
};

/*
* Trigger the timeout function to wait for the page to REALLY load,
* and then release the document READY hold.
*/
waitForPageToLoad();
Share

Dynamically remove blank cells from a column in Excel

This is another Xcelsius issue i had — but the solution is usable in any excel spreadsheet.

I wanted to create a fake drop down (custom image w/ little arrow like most web pages have now + push button + list box) that i could set up with dynamic options — dynamic meaning different options based on different states of the dashboard, not adding or removing new options at runtime.  The problem was that i needed to link to a range in the Excel spreadsheet that gave me the currently available options and did not have blank spaces between them.  I hunted on the internet and found an example, but it used functions that are not available in the Xcelsius-enabled list of Excel functions.

So I edited it to be Xcelsius-friendly and here it is (click on this pic to see a larger version):

Table layout for dynamically removing blank cells
Basic table layout for setup
  • Column 1 (H): a row number that is copied across to column 4 when the option text is marked as “available” in column 3.  these are hardcoded numbers.  Xcelsius doesn’t support the ROW function.
  • Column 2 (I): The table of data.  In my case it doesn’t have spaces, but effectively does when i have certain options marked as “unavailable”.
  • Column 3 (J): A formula that is unique for each row and determines if THAT row should be available.  This checks the status of different things in the Xcelsius file (e.g., the dynamic visibility of other components in order to determine what tab on on, etc) and determines when this option should be available in my faked-out combo box implementation.  If you have data that has spaces in it that you are removing, this row can check for that or (even better) just combined with column 4.
  • Column 4 (K): A filter.  If this row is “available”, then this cell is set equal to the row number in column 1.
  • Column 5 (L): blank… i left it there for spacing, or maybe for adding something later… i don’t know.  I can’t remember.  but it is blank.
  • Column 6 (M): The magic happens here… Keep reading

The function in Column 6 is this, the column letters are defined in the column definitions above (i.e., column 1 is H) and the first row of that table was at row 30:

=IF(ISERROR(SMALL($K$30:$K$49,H30)),"",INDEX($I$30:$I$49,SMALL($K$30:$K$49,H30)))

To break this down:

  1. ISERROR(SMALL($K$30:$K$49,H30)),””…: The first part here checks if there is a next smallest value in column 4.  if there is, it continues to the INDEX function, otherwise it leaves the cell in column 6 empty.  Column K is the sparsely populated filter column (aka column 4), and the “n” in the “nth next smallest value” comes from column H (the rownum).
  2. INDEX($I$30:$I$49,SMALL($K$30:$K$49,H30)):  Since we know an “nth next smallest value” exists in the filter column, this pulls the “option text” in column 2 (i.e., the table data) corresponding to that row number.  the row number starts at 1 for the first row, so it is equal to the “index” of that row when using the INDEX function.
Here is a screen shot to help you line up the formula to the columns.  If you setup the first cell in column 6 with the same “$” that i use for static cells, then a copy-down will fill in that whole column correctly:
Options table with formula 1st row
Showing the super awesome formula in the last column

It is actually pretty simple and useful.  I simplified it as i wrote it here because i found a function that I was using that was redundant, but in case it solved some other issue that i don’t have and can’t think of, here is it:

=IF(ISERROR(SMALL($K$30:$K$49,H30)),"",INDEX($I$30:$I$49,MATCH(SMALL($K$30:$K$49,H30),$K$30:$K$49,0)))

.   The MATCH at the end there is redundant.  In my example, the relative index is also equal to the “nth next smallest value” in the filter column — so i’m doing a MATCH using the SMALL function to get the same number the SMALL function already returns.  It is useful to write these posts and fix my own code!

Share

Dropbox install on Fedora 14

I started using Dropbox and couldn’t get it installed on my 64 bit fedora 14 machine.  I found the solution and am just reposting here to hopefully guide someone to it quicker than I was able to find it.

Here is the dropbox forum page with the information and description of the issue (the answer that worked for me is the last post, by P K.)

Here is the solution in case you have dropbox installed, it is not working, and you don’t want to go through the forum post:

execstack -c ~/.dropbox-dist/_ctypes.so

If you haven’t installed it yet, here’s how I did it:

  1. I downloaded the fedora rpm file from the dropbox site.  Get it here.
  2. I installed it using yum localinstall <packagename>.rpm.  This gave me “missing public key” error.  The solution here was to edit (as superuser) the /etc/yum.conf file and temporarily disable gpgcheck (ie, change gpgcheck=1 to gpgcheck=0).  Edit the file with something like sudo gedit /etc/yum.conf
  3. You can skip this step, unless you want to see the problem.   Once installed, run dropbox — either from the command line or the from the Application Launcher, under the Internet folder.  This says you have to run a daemon, press OK.  It says it is downloading and unpacking… and never finishes.
  4. Don’t forget to go back into /etc/yum.conf and reset gpgcheck=1
  5. In the terminal, type execstack -c ~/.dropbox-dist/_ctypes.so <enter>
  6. Now, run dropbox from either from the command line or the from the Application Launcher, under the Internet folder.
That’s it.  It is working for me.  I was using the Dolphin file explorer but dropbox installs into the Nautilus file explorer… so i’m using that now.  Dolphin crashed often for me anyway, so i was never really attached to it.
Share

Set up PhoneGap with Xcode 4(.0.2)

I had to set up PhoneGap on Xcode 4 yesterday and found many confusing, wrong, or just outdated pages describing how to do it.  I think they fixed some things in PhoneGap 1.0.0, so the install is much simpler than what these pages were saying.  So here is my version which worked for me:

  1. Download and install PhoneGap 1.0.0 on your mac.  Get it here.  This downloads a ZIP file.  Open it up and run the DMG file installation in the iOS directory.  The instructions I saw said to have Xcode closed at this point, which I did.
  2. Open Xcode and create your new PhoneGap project.  This will set up everything except the www directory.

    New Phonegap Project in Xcode
    New Phonegap Project in Xcode
  3. In Finder, navigate to your project (mine is in my home directory under ‘Xcode projects’).  Copy the www directory from <Macintosh HD>/Users/Shared/PhoneGap/Frameworks/PhoneGap.framework/ and paste it into your project in the same directory as the *.xcodeproj file (i.e., your project’s root directory)
  4. In Xcode, right click on the top-most project header (the blue-ish project header block that contains the entire project) and select “Add Files to <your project name>”.  Find and select the www directory that you just placed in your project, and make sure to change the “Folders” radio button to “Create folder references for any added folders”.  Press Add.  Your project should look like this:

    Final Project in Xcode
    Final Project in Xcode
That’s it.  Select the correct simlulator or iOS device scheme at the top of the project window (next to the RUN/STOP buttons), press RUN and the project should build and start up with the “PhoneGap works!” message.  Now you can continue doing whatever you were planning in the www directory.
UPDATE: there is a specific page for this on phone gap that I had not seen… go to it here.  There are still a lot of pages out there that have bad Xcode 4 info on them though!
Share

Having one iframe watch for other iframes to load.

This is an issue that I thought was going to be straight forward using the jQuery ready function, but i could not get it to work.

The problem is simple: I want to watch a couple of iframes load and then do something once they are all done.

The “when they are all done” part is simple with jQuery Deferred objects.  A really good, quick tutorial on those is here.  Basically, I can pass however many Deferred objects I want to the jQuery.when( ... )  command.  When all of them “resolve” (i.e., when the are done doing whatever they need to do), the when command will continue with some “success” function or functions.  There are also options for when one or more Deferred objects fail, etc.  Read the tutorial… it’s good.  I created a javascript object that encapsulates the Deferred object and my method of resolving the object.  So I just needed to create one per frame I wanted to watch and feed them into the jQuery.when() function.

So for the “watch a couple of iframes” part I want to resolve my Deferred objects, instantiated in iframe A, based on iframes B, C, and D finishing loading.  I assumed this was a simple something like:

jQuery(top.B.document).ready( function() { ... resolve my deferred object ... } );

however, this did not work!  It did not matter that I put top.B.document (this is a path from top down to the frame, and then referencing the frames document), the call seemed to work on my local iframe’s document (iframe A in this example). I couldn’t find any information on this online, so if anyone knows more about it i’d love to hear it.

The solution:

I could have gone into each iframe and placed a document ready function that set a flag, and then read that flag from the iframe that is watching, but I wanted to keep this functionality clean and encapsulated in my object that was also handling the Deferred object.  I wanted to write it once — not X number of times.  Also, I know someone will mention “why are you using iframes at all?  use Ajax and blah blah blah”  I know, but you have to work with what you’re given sometimes… so i’m using iframes.

The solution I came up with is this (most of the Deferred object stuff is left out):

// Constructor
function MyIframeWatcherObject( contextPath ) {
...
// Get the path to the iframe we're watching.
this.contextPathToUse = contextPath || null;
...
{

MyIframeWatcherObject.prototype.resolveOnDOMloaded = function( ) {
	// Re-eval contextDocument each time because it is lost when page reloads.
	var contextDocument = document; //default
	try {
            if ( this.contextPathToUse )
		contextDocument = eval(this.contextPathToUse + '.document');
	} catch ( err ) {
		// Do nothing, use default as contextDocument as fallback for now..
                // Add error handling...
	}
	if ( contextDocument.readyState === 'complete' ) {
            deferredObject.resolve();
        } else {
            var self = this;
            setTimeout( MyIframeWatcherObject.prototype.resolveOnDOMloaded.call( self ), 100 );
        }

}

First, I resolve the contextPath that was passed in to get its document.  I do this each time because if I resolve it in the constructor and store it, I lose it if the page begins to reload again (it becomes undefined).  Then I check the readyState on the document and determine if I should resolve the Deferred object now, or set up another timer.  The setTimeout function is best here so that I am only setting up one more trigger each time and don’t have to worry about tracking it like I would with setInterval.  John Resig has a great tutorial on timers here — definitely a good read if you are not aware of how they function.

I’m not completely thrilled with this solution, but it works.  Please offer another way of doing it if you know one!

UPDATE: just an additional note. The document.readyState property looked like it was a cross-browser solution based on my quick google search — otherwise I would not have considered it. If you know differently, or know of bugs with this method, please let me know. Also, the opposite state of document.readyState == 'complete' is document.readyState == 'loading'.

Share

new blog

This is the first post on geekin!  It may take me a while to get things rolling, but i plan on covering topics that relate to my work.  I’m a java developer at B6 Systems in Pittsburgh, and I also handle a lot of web development.  So this blog will cover a wide range of topics like java, web scripting, web design, jsp, whatever else I can think of.

disclaimer: I’m new to web development.  If my ideas seem strange or misguided, make a comment.  i’d love to find out how to do whatever it is better.

Share