Wednesday, January 6, 2010

Flex, FlashVars and your ASP.NET page

So, I spent some time earlier today researching an issue that I had some trouble finding a straightforward answer for. A current project I am working on is a Flex Application that will be embedded inside an ASP.NET page. I needed for the ASP.NET page to pass some credentials and variables to the Flex Application that will be used to process some data. Seems pretty straightforward, and I know it can be done, I just haven't done it before. My .NET is a bit rusty, and the folks I'm working with have not tried passing variables to a Flex application or Flash file before. Now, I knew this could be accomplished via FlashVars inside an HTML page. The question I had was how to pass dynamic variables into the FlashVars via .NET and utilize those inside my Flex Application.

That particular subject was tougher to track down than I thought. Most of the information I found was using some Visual Studio Add-In tool to display Flash files, or some forum would have a response to try
<%= %>
and see if that worked, without much more detail. Now I realize, that if you are an ASP.NET guy, it makes perfect sense. For those of us with weak ASP foo, I realized that would give me a variable, but how to populate that variable? So I dug around some more, experimented, failed some more and after about 45 minutes of toying around, I found that I could create an asp Label in the ASP page, and use the property to assign variables in my FlashVars. There is a ton of information out there on how to read FlashVars from Actionscript, so I won't bore you with details on that, but I will post my code below. Unfortunately, aspx pages won't work with my hosting, so I can't post a live example, but I think I've made them simple enough that you can figure it out.

My Flex Application that will be compiled as FlashVars.swf
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
addedToStage="init()">
<mx:Script>
<![CDATA[
[Bindable]
private var _name : String;

[Bindable]
private var _session : String;

private function init() : void {
_name = Application.application.parameters.name;
_session = Application.application.parameters.session;
}

]]>
</mx:Script>
<mx:Style>
Label {
fontFamily: Arial;
fontSize: 14;
fontWeight: bold;
}
</mx:Style>
<mx:Label text="Name: { _name }" />
<mx:Label text="Session: { _session }" />
</mx:Application>
Here is what the aspx page looks like.
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<style type="text/css">
.style1
{
font-family: Arial;
font-weight: bold;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div class="style1">
<asp:Label ID="Label1" runat="server" Text="My Name: "></asp:Label>
<asp:Label ID="MyName" runat="server" Text="myName"></asp:Label>
</div>
<div class="style1">
<asp:Label ID="Label4" runat="server" Text="Session: "></asp:Label>
<asp:Label ID="SessionLabel" runat="server" Text="Session"></asp:Label>
</div>
<!-- SWF in ASP.NET -->
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab"
width="500" height="500" id="myFlex" viewastext>
<param name=myswf value="swf/FlashVars.swf">
<param name=quality value=autohigh>
<param name=bgcolor value=black>
<param name=”menu” value=”false” />
<param name="FlashVars" value=”init=yes&check=true&name=<%=MyName.Text%>&session=<%=SessionLabel.Text%>&”>
<embed src="swf/FlashVars.swf" flashvars=”init=yes&check=true&name=<%=MyName.Text%>&session=<%=SessionLabel.Text%>&” quality=high bgcolor=#FFFFFF width="30" height="56"
name="myswf" type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer">
</embed>
</object>

</form>
</body>
</html>


Here is the key part from above. This is your FlashVars that has values that are tied to Lables in the asp page whose values are changed from the code-behind. It should be pretty simple to change this with any data you want .NET to pass on.
<param name="FlashVars" value=”init=yes&check=true&name=<%=MyName.Text%>&session=<%=SessionLabel.Text%>&”>

Here is the code-behind for the aspx page.
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.MyName.Text = "odoenet";
this.SessionLabel.Text = Session.SessionID.ToString();
}
}

You can make this label hidden or maybe find a different way to bind your FlashVars. I just found this to be the simplest way to show how it can be done. If someone has a better solution or experience with this, please let me know.

It might also interest some of you to check out this page about passing data to and from .NET web services and Flex applications. I was looking for this to find out how I can pass either an Array or as it turns out an ArrayCollection to a .NET Web Service to update a database.

Again, I realize this isn't ground-breaking material here, but I thought that if I had a tough time finding a straight answer, maybe some else will too and this might help them out.

Friday, December 11, 2009

ESRI Flex Map with Robotlegs

Well, I'm not really one to leave well enough alone and I just had to give another Flex framework a try for my ESRI Flex mapping needs. My latest victim was Robotlegs. If you look at my earlier blog postings, you might have seen me mention that my first Flex framework was Cairngorm. I didn't really dislike Cairngorm, but after some conferences and reading around, I felt like I should expand my Framework horizons. Most recently I have been using Swiz with a lot of success. I think I use Swiz in the most minimal way possible, which is actually something for a future blog posting.

But I had also tried at one point to give Robotlegs a try. I had worked through some of the docs, but had not really dived into any of the examples. So I finally decided that I needed to get my feet wet a bit and dived into some reading material. Joel Hooks had a posting of a presentation that I particularly enjoyed. So after some trial and error, I think I wrapped my head around the basics of Robotlegs. Like Swiz, Robotlegs utilizes metadata to support Dependency Injection in the framework. I'll be honest here, I'm spoiled, I don't know how to do dependency injection in Flex/AS3 manually. Adding that to my list of things to learn. Anyway, this makes tying classes and events together pretty simple.

After a couple of hours of watching videos and creeping through some examples, I was able to come up with this example, with view source enabled of course. Now, as far as Flex Mapping applications go, this is about as simple as it gets and as far as I wanted to go tonight as it's getting late. But the basics are in there. You have a map, with it's layers and extent tied to a model. You have a datagrid tied to a custom ListCollection ( I took portions of this from another project I'm working on ) and a graphicslayer that gets highlighted when you click on the datagrid. And of course a QueryTask to handle getting attribute information. Most folks that work with Flex Maps using the ESRI Flex API will be familiar with this and realize this is probably the starting point for about 90% of your projects.

Now on to my impressions of Robotlegs. I will say this, Robotlegs got me in the mindset of the Single Responsibility Principle when I was going through my project. For example, I have a command to query the States Service and a command o handle the results. In most of my recent work, I had one controller doing both those tasks. Now, I'm not going to go "programmer purgatory" for using my controllers that way and the only coding cookie I'll get for wanting to follow that principle is the sugar cookies my wife and kids make, but it is one of those things I have found makes maintaining and testing of code easier. My only complaint would be is that I found, even looking at examples, is that the code started looking a little "Cairngormish". By that I mean, I had to manually wire my events to my commands. This started looking an awful lot like the FrontControllers I'd seen in previous apps.

One other thing bothered me, but I'm sure it has more to do with my following examples as opposed to really knowing how to use the framework is the need to override functions and extend Robotlegs classes for everything. Something I have been trying to do, is keep 3rd party APIs that aren't specific to the output of my app as minimal as possible. That's actually a topic for a later post, but it was something I found odd as I worked through my first real attempt. But like I said, I have a feeling that as I get more familiar with Robotlegs, I can find a nice balance to keep the framework implementation as minimal as possible. Something I really liked was the Mediator for views. I have been using the Presentation Model on my most recent work app and I'm a big fan of using a model for my view that can be tested independently. The Mediator class in Robotlegs is a very nice way of keeping your views as "dumb" as possible.

So, that's it for my first run at Robotlegs. I'm going to dive into it some more and try some things to see how I like using it most. I'm sure the more I use it, the more I'll enjoy it. It's nice having another tool in my Flex toolbox that I can pound on something with.

Wednesday, December 9, 2009

Highlight Map from List Items

I was inspired by this posting on the ESRI ArcGIS Server Blog filed in the Flex tag, that linked your graphics on a map with a DataGrid. This is a useful function and one I thought could be encapsulated into it's own task. In my case, I just had a need to highlight a graphic on my map that was associated with a list. I did not need to highlight the list when I hovered over the map because I have designed my Graphics with tooltips and felt that two-way binding would be "too much" flash for business purposes. You certainly encapsulate that function and if I were to do so, would probably build it into a utility type of class. With that said, here is the code.
package net.odoe.model.graphic
{
import com.esri.ags.Graphic;
import com.esri.ags.geometry.Geometry;
import com.esri.ags.layers.GraphicsLayer;
import com.esri.ags.symbol.SimpleFillSymbol;
import com.esri.ags.symbol.SimpleLineSymbol;
import com.esri.ags.symbol.SimpleMarkerSymbol;
import com.esri.ags.symbol.Symbol;

public class HighlightGraphic extends Graphic
{
protected var _defaultSymbol : Symbol = new Symbol();

/**
* This function will save the default graphic symbology
* highlight the graphic for the currently selected item.
* @param data that holds attribute information; i.e. from a ListEvent (event.itemRenderer.data).
* @param graphicsLayer that holds the graphics that can be selected.
* @return a higlighted graphic.
*
*/
public function setHighlightGraphic( data : Object, graphicsLayer : GraphicsLayer ) : Graphic {
if( graphicsLayer ) {
_defaultSymbol = findGraphicByAttribute( data , graphicsLayer).symbol;
return featureHighlight( data, graphicsLayer );
}
return new Graphic();

}

/**
* This function will reset the previously selected graphic
* to its default symbology.
* @param data that holds attribute information; i.e. from a ListEvent (event.itemRenderer.data).
* @param graphicsLayer that holds the graphics that can be selected.
* @return default graphic.
*
*/
public function resetDefaultGraphic( data : Object, graphicsLayer : GraphicsLayer ) : Graphic {
if( graphicsLayer ) {
var _graphic : Graphic = findGraphicByAttribute( data, graphicsLayer );
_graphic.symbol = _defaultSymbol;
return _graphic;
}

return new Graphic();

}

//------------------------------------------------------------------------------------------------------
//----PROTECTED METHODS---------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
protected function findGraphicByAttribute( attributes : Object, graphicsLayer : GraphicsLayer ) : Graphic {
for each( var graphic : Graphic in graphicsLayer.graphicProvider ) {
if ( graphic.attributes == attributes )
{
return graphic;
}
}
return new Graphic();
}

protected function featureHighlight( data : Object, graphicsLayer : GraphicsLayer ) : Graphic {
if( graphicsLayer ) {
var _graphic : Graphic = findGraphicByAttribute( data, graphicsLayer );
_graphic.symbol = highLightSymbol( _graphic.geometry );
return _graphic;
}

return new Graphic();
}

protected function highLightSymbol( geometry : Geometry ) : Symbol {
if( geometry.type == Geometry.POLYLINE ) {
var _highlightLineSymbol : SimpleLineSymbol = new SimpleLineSymbol;
_highlightLineSymbol.color = 0xFF00FF;
_highlightLineSymbol.width = 10;

return _highlightLineSymbol;
}
if( geometry.type == Geometry.MAPPOINT ) {
var _outline : SimpleLineSymbol = new SimpleLineSymbol;
_outline.style = "solid";
_outline.color = 0x0000CD;
_outline.width = 2;

var _highlightPtSymbol : SimpleMarkerSymbol = new SimpleMarkerSymbol;
_highlightPtSymbol.style = "circle";
_highlightPtSymbol.color = 0xFF00FF;
_highlightPtSymbol.size = 15;
_highlightPtSymbol.alpha = 1;
_highlightPtSymbol.outline = _outline;

return _highlightPtSymbol;
}
if( geometry.type == Geometry.POLYGON ) {
var _outlinePoly : SimpleLineSymbol = new SimpleLineSymbol();
_outlinePoly.style = "solid";
_outlinePoly.color = 0x0000CD;
_outlinePoly.width = 2;

var _highlightPolySymbol : SimpleFillSymbol = new SimpleFillSymbol;
_highlightPolySymbol.style = "solid";
_highlightPolySymbol.color = 0x00FFFF;
_highlightPolySymbol.alpha = 0.3;
_highlightPolySymbol.outline = _outlinePoly;

return _highlightPolySymbol;
}

return new Symbol();
}

}
}


I have made the functions in here protected, as I found a need at a later time to extend this class and override the protected function findGraphicByAttribute to recognize a particular attribute field (i.e. graphic.attributes.Name == attributes.Name) and not just all attributes.

I made an example of the function just like the one on the ESRI ArcGIS Server Blog using my class.
It can be found here with View Source enabled. Hope this benefits someone.

Wednesday, November 4, 2009

ESRI Flex Application using Presentation Model Pattern with Swiz

So continuing on my quest to be a better developer, I have really dived in deep to the Swiz framework.I have learned quite a bit since my last postings and I think I have gotten a really solid grasp on how to leverage the framework to meet my needs. Inspired by Ben Clinkinbeard's Presentation Model Pattern using Swiz, I set out to try and build an ESRI web mapping sample in the same manner.

So, I read through some of this in addition to Ben's example above and this how I interpreted using the Presentation Model Pattern.

( I prefer yellow sticky notes for complex explanations )

What I liked about this pattern was that I'm able to keep the view as dumb as possible, so less can go wrong from here. The Presentation Model represents what happens in the view including values and events. The Presentation Model is responsible for dispatching events you would normally dispatch from the view. Controller does the work, utilizing delegates when needed and updating Autowired values to the model. If you look at the source for my example, you'll see I made some comments about having issues with a couple of Autowired items that I could not get to update directly in the Controller, I had to set custom setValues(value:Object) setters for the model and use that. I would prefer the Controller not even be aware of the model, and I think I may be able to accomplish this with an IEventDispatcher and using the Controller as a Protocol in my SwizConfig, but for the points I was trying to illustrate, I don't think it was really needed here.

You may also notice I am using FlexUnit 4 to do some testing. I am just now starting to utilize unit testing as I build my applications and FlexUnit 4 has some nice features I am playing with. Testing is part of the reason I want to try and keep my Presentation Models and my Controllers as independent of each other as much as I can, to prevent any funny business from occurring when I try to maintain my tests as an application grows.

This is just another of my experiments in my quest to be a better developer. As I have said before, I just kind of fell into this, so a lot of these concepts are still new to me. I'm fairly comfortable with the ESRI Flex API at this point. Now, I'm trying to really grasp how to use design patterns and testing practices to improve my work.

Friday, October 23, 2009

Swiz and the ESRI API, we meet again.

So, I spent quite a bit of time this week really trying to wrap my head around using the Swiz framework with the ESRI Flex API. I found the actual Swiz website, which somehow never came up in all my earlier research. It gave me some details on things I wasn't clear on before.

I also found this video by Joe Rinehart, Swiz in 20 minutes.
Videos like this are great, because it just helps to hear and see someone go through it from start to finish. With my new found information, I was ready to tackle a new version of the application I posted earlier. What I have found, is the Swiz framework really gives you a lot of freedom in how you actually want to write your code. How I use it in my style, may not work for someone else's style. I really like that. You can also get a good explanation of the framework and metadata here.

So, rewrote my previous example, to incorporate a tighter distinction between views and controllers. Found here (source available).
I now make liberal use of the Autowire metadata, which links all my functions and variables through my beans. I'm also making good use of the Mediate tag, that will capture events.

For example, in my Controller, I have this.
public static const QUERY_LAYER : String = "queryLayer";

Then, from any other view or controller, I can use this.
Swiz.dispatchEvent( new Event( LayerController.QUERY_LAYER ) );

In my Controller, I have this.
[Mediate( event="queryLayer" )]
public function queryStateLayer() : void {
trace( "begin queryStateLayer" );
Swiz.dispatchEvent( new Event( LayerController.LOAD_STARTED ) );
var query:Query = new Query();
query.returnGeometry = false;
query.outFields = [ "STATE_NAME", "AREA" ]
query.where = "STATE_NAME <> ''";
AsyncToken( stateDelegate.execute( query ).addResponder( new Responder( state_results, state_fault ) ) );
}

Using the Mediate metadata, telling it to watch for the "queryLayer" event, it will fire this function whenever that occurs.

As can be seen above, I am using the AsynToken function to call a delegate that will execute my query task. You don't need to use a delegate. You could execute your task directly in the controller. I like to keep my delegates separate only because it makes sense to me, as my first framework was Cairngorm and that was pretty standard. I also think it keeps the controller a little cleaner.

My biggest hurdles were trying to interpret many of the Swiz tutorials to fit into an application with an ESRI Map control, where you want interaction between the map, the layers and your controls. Swiz now supports adding Views to your beans, although from what I have read, you may want to do so only in special circumstances. But that could be another option, is to add the Map into your beans and open it up to all controllers and functions in your application.

One big hurdle that I have not been able to figure out is Unit Testing with the Swiz framework. I have tried with Fluint and Flex Unit to no avail, although I have heard that the Autowire and separation of controllers should really make this a simple task, especially in Fluint. When I try in Fluint, I load my beans in override setUp. I Autowire my controller and models as I think I should. I can dispatch an event to my controller and my trace show that my app runs just as it should, but when I check an Autowired value such as an ArrayCollection, it's null, even though it should not be. It's driving me nuts. I'm having the same issue with Flex Unit, my application traces show everything runs, but at the end, my Autowire values are still null.

If someone could look at my example and maybe write a quick Fluint or Flex Unit test for say the StateListCollection, I would be eternally grateful as it would really just push me in the right direction. I was hoping to incorporate unit testing from the very beginning of all my future applications, but this is really just killing me now.




Sunday, October 18, 2009

Mapping apps with Flex, Swiz and Fluint

I have been developing with Flex for about a year now and so far it has been a really fun experience. I am by no means a trained developer, I just happened to have taken some some C++ and VB6 courses in school and fell into it.

That being said, I had very little clue how to use a framework when developing, much less how (or why for that matter) to do unit testing. I saw a great presentation at the ESRI 2009 Developer Summit last year on Flex Best Practices. It was in that session that I learned how much I had been doing wrong. I guess, I shouldn't say wrong, after all, the application I was working on worked. Problem was, when someone wanted to add a new feature or change the way something worked, I found myself spending a lot of time trying to fix things I had broken by doing so.

That's when I first started using Cairngorm. This site has some great articles and videos on Cairngorm. That's where I learned how to use it. Cairngorm seemed like a great way to organize my code and in the end it just made sense. It can be a little clunky and as I have read elsewhere a bit heavy on boiler plate code. You launch an event that's tied to a command that executes a delegate and then process the results updating your model. Makes perfect sense to me. Then I discovered unit testing. It was discussed in that presentation I mentioned, but I didn't think it really applied to me. After all, I was the only person developing this application and why would I need unit testing, Cairngorm kept everything organized for me. That is until my model got a bit large, my commands dispatched more events to more commands, I was using timers to keep consecutive asynchronous tasks to the same functions from overlapping and I found a change here would break something somewhere else and would go unnoticed until I tried to show someone something cool I had done only to find something else didn't work (yeah, that looks really cool).

So, like any Flex developer would do (I actually have no idea what a real Flex developer would do) I tried out FlexUnit. FlexUnit worked and looked good too. However, have you ever tried to do unit testing with Cairngorm and FlexUnit? Do a web search on that particular subject. It took me a few tries, but I got something working. I realized at this point why Test Driven Driven development has such a good reputation. It works. I've decided to approach all my future projects this way.

But I thought this post was titled "Mapping apps with Flex, Swiz and Fluint", why am I rambling on about Cairngorm and FlexUnit? This is my first blog post, give me a break. Did I mention that the only Flex development I have done is mapping applications with ESRI's Flex API? Now, I know I'm not alone in having my first Flex experience be with the ESRI Flex API. It's fairly new and it's a niche market. We are a niche group. Now out of that group of ESRI Flex API developers (I use the term developer loosely for myself) also use a Framework of some sort? Okay now, I know this list might be short, but out of that group, how many are doing or attempted test driven development?

You can see where I might have been frustrated trying to research that particular subject. When dealing with a mapping application, there is a lot going on. You have a map that you might want multiple functions to access and adjust an extent for, you have multiple map services that you want exposed to other functions so you can turn off layers or adjust transparencies, not mention use query tasks or identify (I'm sure it's just as bad for you real Flex developers if not worse). A framework really lets you get a good grasp on these things. Utilizing testing of some sort is just a cherry on top. Because of some frustrations I had with Cairngorm, I decided to research some more frameworks that I thought lent themselves quite well to mapping applications specifically.

That's when I turned to Swiz. I really did not like Swiz when I looked at it. I mean, come on, Beans? I thought that was a Java thing? But I decided to buckle down and really take a crack at it. So I took one of the ESRI Samples from their website and adjusted it to work in the Swiz framework with some minor tweaks to display a grid of state names. That took me a full Saturday. Being the overambitious glutton for punishment that I am, I decided to try to do some unit testing with Fluint. But why not Flex Unit you might ask? Fluint was touted at the 2009 Developer Summit I went to as being a little more robust. Plus, I figured, I wanted to learn something new. Fluint has some nice features, and I think the most powerful is the ability to add steps to your test and then run it.

So, after spending all weekend, reading multiple tutorials, multiple blogs and forum posts, I got a working, testable (and passing thank goodness) application put together. I figured, someone out there, might be in my situation. Using the ESRI Flex API, trying to wrap their heads around a framework and maybe, just maybe trying to do some unit testing. I did not find a specific example like that anywhere. If you got one, please share it.

Remember, in my example (view source available), I am probably doing a lot wrong. I have my map in my Beans (that sounds hilarious) with a controller, a delegate and a component to control my list of states. I'm kind of thinking that in the way I'm using it, my Beans replace my model. It exposes what I want to everything else in my application. Originally, my map was just part of a single component with a datagrid. I parted it out, so that I could add a function to zoom to a state on a datagrid double click. I need my map accessible outside that page. I probably make some wrong assumptions here, but I haven't tried that part yet.

If you are curious on what sites I used as references, here is a list.
Brian Kotek had an awesome 5-part series on Swiz. There is supposed to be more coming, so I'm sure I'll change how I use it as I learn more of the stuff he didn't post yet. Not to knock the Swiz Getting Started page, but I had a tough time really grasping it with their walk-through.

This insideria article gave me a good start at using Fluint. The Fluint Getting Started pages were a big help as well.

And if you bothered reading all this, I assume you are interested in Mapping applications using Flex with a framework while taking advantage of unit tests. I hope I have helped in your unholy quest.
Sorry, if this wasn't "tutorial" or more specific. If someone has questions (all one of you), I'll try to answer them the best I can. The couple of guys linked above know more than I do about Swiz and Fluint, but I have a newbie perspective on it when it comes to the mapping stuff if you need it. I'll probably still use Cairngorm for stuff already done that way, so might post an example up with that later on. I'm hoping to tackle Mate next weekend, so we'll see how that one goes.