Friday, December 25, 2009

How to get freelance work

During 3 years of successful freelance work, I have several times been asked by friends and family members "how do you get work" or "From where do you get work". This blog post is to answer these questions. I am going to update this post soon so stay following me.

Ok so here I am to tell you my secrets of getting work online. First and foremost thing I want to tell you that there are many fields in which you can find freelance work. Here I am listing few fields for which I saw posts on freelancing sites.

1) Teaching
2) Writing
3) Software development
4) Data Entry
5) Website management
6) Software testing and QA.
7) Palmist
8) Psychiatrist
9) Medicine

I am sure you can add many more fields if you search it on the internet. My experiences are related to software development but the key points I am discussing here will apply to the other fields as well.

Now the question is "how to get the work of your interest"? Well there are thousands and thousand of sites offering you to start your online business. Like for software development famous sites are rentacoder.com, elance.com, scriptlance.com and odesk.com. I have worked with rentacoder and elance. Both are robust but I was able to make good profit at elance because of their low fees. For teaching there are tutor.com and liveperson.com.

There are many sites which allow you to create a free account and start bidding for the jobs. Many sites ask you to pay a certain amount to create an account. I would recommend that you consider a free account to start. You may switch to paid service later if you get success in your business.

To create an account was the easiest part of the job. After you create your account you will be able to see the job posting and you will be able to post your comments and pricing to do that job. Reading the post is also easy task but responding to them and making bids is a difficult task. To me following points are important.

1) Read the problem carefully many times.
2) If you think that you can work on the project but you don't understand it fully, write to the buyer immediately. Because it is important to communicate on urgent basis. At rentacoder.com I found that there were messages and bid from other providers within minutes after a new project was posted.

3) Do not bid if you don't fully understand the requirements.

4) If you understand the requirements and can work on the project try to be the first or among the first few who placed the bid. Yes you will have to be very quick. You know the buyer sometimes gets tens of bids, he cannot read each bid and cannot respond to everyone.

5) Tell him the truth. I have seen providers asking you to finish work in two days while the work cannot be done in less then one week. Do tell them that you cannot deliver in 2 days.

6) Respond quickly and promptly. If you receive any query from the buyer respond quickly. Its better to keep checking your emails after other hour to make sure that you will be able to reply him quickly.

7) You may offer him demo of small part of the work he wants. My second project at rentacoder was an online file management system. After reading the requirements I made the bid and within few hours I created a short demo for that. I showed him my work and he was surprised with the quick work and immediately approved my bid.

8) Write a proposal. Its better to write proposal to make bid. What I do is that if the work is small I simply write my proposal in an email message. Like once I was given work to add one field in a form in php. I wrote following points to the client

a) I have to put the html code to add this field.
b) I have to write javascript validation of this field.
c) The is a username it needs to checked for duplicate entries, so I need to put ajax based validation from server.
d) I have to write code to handle and show error.

Above points show that I fully understand the problem and it also lists the tasks that need to be done. By doing this you are making it easy for the buyer to choose you.

If the work is more complicated then write a neat proposal. List all the modules and what you think will be done in each module. Put pricing and hours/days for each modules separately. It ensures that you understand the requirements. It is often better to multiply the estimated time with 2. But never multiply the estimated cost by any number :).

9) If you get the work start immediately. Divide the agreed upon number of days by 2 and take the result as your deadline.

This is all I do. Sometimes my project goes well beyond the deadline but my clients are satisfied at the end. Just because I do all my work with all my honesty and sincerity. If you succeed to get you project and you deliver quality work on time then it is easier to get more work.

If you are also a freelancer, I would love to hear your story. Please share your experiences with us.

Thursday, December 10, 2009

GXT grids - Binding with beans

I had to use many grids in my first GXT project. I got to know that I have to use GXT right after I sent my first release of the front end to the client. I had never used GXT, the deadline was tight. I was puzzled, should I spend time in understanding the library or just start coding with the help of google. I started coding the simpler screens, I was able to show some progress to the client in next couple of days. I turned to the grids after writing all the screens in which there were no grids. I opened their demo and tried to understand the code – I was failed. I started experimenting with the examples and tried to copy it with my classes – I got no success. I searched the internet and I found one description copied to many places by different authors. The description was not enough for me. I read it again and again and tried to implement it in my application. After many trial and errors I was successful. Following is a detailed description of problem and solution.

I had prewritten data access objects which I had to use for grid data binding. I found a good tutorial for this at gxt site at following link

http://www.extjs.com/helpcenter/index.jsp?topic=/com.extjs.gxt.help/html/tutorials/beanmodel.html

After I read the above I did following steps

1) Implement BeanModelTag in all beans. Following is an example of TimeZone bean which contains Timezone record from database.

public class TimeZone extends LightEntity implements Serializable, BeanModelTag
{
private int id;

private String name;
private String defaultValue;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getDefaultValue() {
return defaultValue;
}

public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
}

Note that it is serializable and it is marked as BeanModel by implementing BeanModelTag interface.

Next step is to fetch data from the database. My service implementation returns an ArrayList of above bean and it is as follows.


public class TimeZoneServiceImpl extends PersistentRemoteService implements
TimeZoneService {

public TimeZoneServiceImpl() {
super(HibernateUtil.getBeanManager());
}

@Override
public List getAllTimeZones() throws Exception {
Session currentSession = HibernateUtil.getSessionFactory(false)
.getCurrentSession();

List timeZones = DataCubeUtil.getTimeZoneList(currentSession);

return timeZones;
}

}

You can call this service as a simple RPC call or you can use gxt RPCProxy which handles callback on its own. Using RPCProxy is easy and straight forward it will bind the grid columns with your beans properties using ColumnModel.

final TimeZoneServiceAsync timeZoneService = GWT
.create(DeviceService.class);
RpcProxy proxy = new RpcProxy() {
@Override
public void load(Object loadConfig, AsyncCallback callback) {

timeZoneService.getAllTimeZones(callback);

}
};

Abovel lines make an RPC call and fetch data from TimeZoneService. But we have not loaded this data yet and we have not provide any grid-data binding configuration. To load data into a store we need a loader, we can use ListLoader or PagingLoader etc. I used a ListLoader in this manner

BeanModelReader reader = new BeanModelReader();
ListLoader loader = new BaseListLoader(proxy, reader);

Here reader is used to handle creating new model instances from the beans being returned from the data proxy. So at the stage when you introduce reader into your code, your actual bean is gone and at runtime the gxt libaray creates its own instance of TimeZone class.

Now I have to create a store which can store the loaded data.

ListStore store = new ListStore(loader);

So far what we have done is that we created a bean, created a proxy which brings a list of beans (filled with data), we created a reader which can read the returned beans, then we created a store and a loader, loader loads data into the store. But how it will bind the loaded data into the grid. This is done by ColumnModel.

ColumnConfig columnConfig=getColumnConfig();
ColumnModel cm = new ColumnModel(configs);

Following function creates binding by setting column id same as bean's properties. Here I would like to mention that while binding the grid column to bean's property it follows java's coding convention. Like the id of column name is "name" (column.setId("name"). While creating the binding at runtime that library find the getter method by concatenating get infront of id, in this example it would be getName(). If this getter is not found gxt will not raise any exception. It simply ignores this binding. For example if the name of getter was get_name() then your binding will not be done as expected. So be careful while creating these bindings.

private ColumnConfig getColumnConfig(){
ArrayList config=new ArrayList();

ColumnConfig column = new ColumnConfig();
column.setId("name");
column.setHeader("Name");
column.setAlignment(HorizontalAlignment.CENTER);
column.setWidth(84);
config.add(column);

ColumnConfig column = new ColumnConfig();
column.setId("defaultValue");
column.setHeader("Default Value");
column.setAlignment(HorizontalAlignment.CENTER);
column.setWidth(84);
config.add(column);


}

After you make the binding your grid is ready to go.

To me gxt grids with their store API is robust solution. You can create grids with checkboxes, with multiple headers, with custome styles for each column data etc. They saved me a lot of time and efforts.

GWT-Ext and Ext-GWT -- some experiences

This fall I started two GWT projects simultaneously. Title of first project was GWT web application development - the specifications were all well written and it was understood that I have to code the application in GWT-Ext. The title of second project was GWT/GXT front end - The specifications were all dirty and difficult to understand, some of the pages were handwritten and scanned. The deadline of second project was difficult. After submitting second milestone of the first project I started coding second project and created almost all the screens in one day. I coded all the screens in GWT-Ext and sent the application to the client with all the source code. He was really shocked and he told me that his previous coder took one month to design these screens. He then sent me the previously written code. When I opened the code the first thing that I noticed was it had used extjs libraries. Now I was shocked oh I had to use Ext-Gwt(GXT) instead of GWT-Ext. I informed the client about it. I was thinking that he might say that using GWT-Ext is fine as it is free, but he said that he wants it in Ext-GWT as he has already purchased the license. So I quickly started to write the application in Ext-GWT, I reused the prewritten code as I had never used Ext-GWT. Soon I got used to of it as it is pretty much similar to GWT-Ext.

Ext-GWT or GXT is a library from famous ExtJs team. It has really powerful and pleasant layout components are easily customizable via css or java code. If you want to display records in tree, grid, combo or tables its proxy-loader-store mechanism is really good even though it is difficult to understand but once you grab it you can easily and quickly create such elements in your application.

When I started coding the second application my thoughts were that gxt is not free so it should be better then GWT-Ext and I assumed that I would get better support at their forum. During my GWT-Ext coding I was caught into several troubles especially in cross browser issues. I had to handle cross browser issues by various tricks in my code. For other problems I had to Google again and again. I was thinking that in gxt I will not be facing too many issues. Everything went fine during my development, but when I ran the application in firefox, I was frustrated with all their bogus cross browser slogans. Drag and drop was not working in firefox and chrome. Grids were not looking good and etc.

I searched gxt's forums and couldn’t find good responses. While in GWT-Ext my experience was different. If you want good support for gxt you should avail paid services at their forum, while in GWT-Ext everything is free.

To me GWT-Ext both are similar and if someone ask me to recommend which library to use my vote goes to GWT-Ext not only because it is free but also because I found good community support at their forum.

My final point for both the libraries is that both are awesome but both have limitations when it comes to cross browser functionality and both fail to provide cross browser widgets. To me that is acceptable as it is nearly impossible to assure that each and every component in the library will behave as expected in at least three major browsers (IE, firefox and chrome).