• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1721
  • Last Modified:

strange problme with IE and ajax call using JQUERY and JSON

Hi i have a code that works absolutely fine in all browsers except IE7 (and may be IE6)

Here is my code architecture

- ASP page  containing Jquery code
- Handler.ashx  server file called by Jquery
- JSON return by the server file
- jTemplate on the client side

when AJAX is called by the IE7 client then it throws an error  
"$T.title is null or not an object"


so why this code is running ok in all browsers  fire, safari and chrome and not in IE7


ASPX page code
--------------------
 
        function GetSectionDetails()
        {
              var k;
              var handlerUrl = "http://localhost:1453/PaggingDotNet/Handler.ashx?op=op2&lid=123&oid=11234999";
              
           
              //$(detailsArea).load(FormatUrl(handlerUrl));
            
              //--------------------------------------------------------
              //ATTENTION THIS LINE OF CODE HAS SOME PROBLME IN FIREFOX 
              //$(detailsArea).html("Loading....");
              //--------------------------------------------------------
              
              //this statement will generate a new random number so that cacheing does not affect the reponse form server.
              handlerUrl = FormatUrl(handlerUrl);
              $.ajax({
                type: "GET",
                url: handlerUrl,
                data: "{}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function(msg) 
                 {
                        ApplyTemplate(msg) 
                  },
                  error: function() 
                  {   
                        alert("Some error occured");
                  }
 
                  
              });
        }        
        
        
        function ApplyTemplate(msg) 
        {   
              $("#detailsArea").setTemplate($("#TemplateResultsTable").html());   
              $("#detailsArea").processTemplate(msg);                 
        }         
 
        function FormatUrl(url)
        {
            var newUrl = url;
            newUrl += '&ver=' + Math.random().toString();
            return newUrl;
        }
 
 
and jTemplate
-----------------
<script type="text/html" id="TemplateResultsTable">   
{#template MAIN}   
<table  cellpadding="10" cellspacing="0">   
  <tr>   
    <th>Title</th>   
    <th>Desc</th>   
  </tr>   
  {#foreach $T.Records as CD}   
    {#include ROW root=$T.CD}   
  {#/for}   
</table>   
{#/template MAIN}   
 
 
{#template ROW}   
<tr>   
  <td>{$T.title}</td>   
  <td>{$T.Desc333}</td>   
</tr>   
{#/template ROW}   
</script>  
 
 
 
 
 
 
 
 
 
and server side ASHX  file code
--------------------------------------
    public void ProcessRequest (HttpContext context) 
    {
        context.Response.ContentType = "application/json";
        
        string s = "";
 
 
            s = "{";
            s = s + "\"Result\":\"ok\",";
            s = s + "\"Param\":\"My Name 121 1989\",";
            s = s + "\"Records\":";
            s = s + "[";
            s = s + "{";
            s = s + "\"title\":\"Title 1\",";
            s = s + "\"Desc333\":\"" + context.Request.QueryString["ver"].ToLower() + "\"";
            s = s + "},";
 
            s = s + "{";
            s = s + "\"title\":\"Title 2 ewf wef wef we fwef we\",";
            s = s + "\"Desc333\":\"My Description 2\"";
            s = s + "},";
 
            s = s + "{";
            s = s + "\"title\":\"Title 3\",";
            s = s + "\"Desc333\":\"My Descewf wef wef ewf wef ription 1\"";
            s = s + "},";
            s = s + "]";
            s = s + "}";
 
        context.Response.Write(s);
    }
 
 
 
 
as you can see the server side code only generates the JSON and returns it to client side

Open in new window

0
shahzad73
Asked:
shahzad73
  • 9
  • 5
  • 3
2 Solutions
 
Michel PlungjanIT ExpertCommented:
Please show the actual JSON produced
0
 
shahzad73Author Commented:
this was the result   Result is just a field to indicate that the processing is ok     param is some information retured.    actual records are withni Records


{"Result":"ok","Param":"Total Record : 3","Records":[{"title":"Title 1","Desc333":"My Description 1"},{"title":"Title 2","Desc333":"My Description 2"},{"title":"Title 3","Desc333":"My Description 3"},]}
0
 
shahzad73Author Commented:
got another code that works fine in all browsers first time but second call throws error in javascript.   error is on the line whichs call Jtemplate

$("#dvDetails").processTemplate(employees);

error is  

"constructor is null or not an object"


i did some debuggig  and instead of calling jtemplate i make an alert.   and looks like call to server is made successfully.     client javascript recreivs the data  and when alert     alert(myobj.Head[1].id);     i am shown a different GUID that is generated dynamically on the server side   BUT  in IE it ALWAYS shows the same GUID that was received first time       ALL other browsers shows a different GUID  
NOW I CANNOT understand why IE behaves differntly




this time my data returned by the server process is  

{ "Head":[ { "id":"59b8fc11-2434-41d4-b44a-99ba84c848a1","username":"user name","firstname":"name 2","lastname":"last name"}, { "id":"4bd08f94-5148-44bc-92c9-f738c430c621","username":"user name 1","firstname":"name 3","lastname":"last name"}, { "id":"160aca2d-6829-4730-9772-460c9d1bd612","username":"user name 2","firstname":"name 4","lastname":"last name"}, { "id":"cc630527-f5ba-478f-a102-42640841b813","username":"user name 3","firstname":"name 5","lastname":"last name"}, { "id":"164b40b0-5804-45fc-9430-32c0461b9f38","username":"user name 4","firstname":"name 6","lastname":"last name"} ]}
        $(document).ready(
        function() 
        {
             $("#ddlDept").change(
             function() 
             {
                var DeptID = $("#ddlDept > option[@selected]").attr("text");
                if (DeptID != 0) 
                {
                    $.getJSON('http://localhost:1453/PaggingDotNet/Ajax2/Handler.ashx', 
                    function(employees) 
                    {
                        
                        var myobj;
                        myobj = null;
                        myobj = employees;
                        
                        //alert(employees);
                        //$("#Div1").html(employees);
                        
                        $("#dvDetails").setTemplate($("#TemplateResultsTable").html());
                        $("#dvDetails").processTemplate(employees);
                        
                        
                        //comments above jtemplate calls and codes does not show an error. following alert shows GUID of first record.  BUT IN IE IT ALWAYS SHOWS THE GUID FIRST TIME RECEIVED
                        //alert(myobj.Head[0].id);
                    });               
                }                
              });
         });

Open in new window

0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
shahzad73Author Commented:
second call always produces the error    "constructor is null or not an object"      and error is i think on the call to jTemplates in javascript when we want to process the template      what's going on
0
 
shahzad73Author Commented:
is there any caching problme in IE that it always shows the same results in every call altgough server is sending differnet data
0
 
shahzad73Author Commented:
i am increasing my points   please give me some solution     or any other code   using  html and javascript on the client side  with jtemplate showing records in table      and    .ashx  on the server side that returns different data.    and also code should work in every browser
0
 
Michel PlungjanIT ExpertCommented:
I thought perhaps the JSON might be malformed
so I tried here
http://braincast.nl/samples/jsoneditor/

but it looks ok.

I hope some jQuery experts can find the issue
0
 
Michel PlungjanIT ExpertCommented:
Yes IE caches ajax/JSON and it is a pain the neck. Try expiring the result using expiry headers or add &rnd="+Math.random()
to the query string
0
 
shahzad73Author Commented:
can u give me some working codes that works in all browsers or give me link online where i can dowload some smaple
0
 
Michel PlungjanIT ExpertCommented:
I have zero experience with ASP.NET and jTemplate, so we will have to wait until someone with such knowledge shows up.
Alternatively delete and re-open the question with the more specific issues
0
 
shahzad73Author Commented:
ok i added a random value to the path and now IE is also showing different values code is given

now i have only problmes with jTemplates notice in the follownig code that i commented these lines

                        $("#dvDetails").setTemplate($("#TemplateResultsTable").html());
                        $("#dvDetails").processTemplate(employees);

if i uncomment the lines and then run then all browsers the code runs fine FIRST TIME ONLY, ajax call goes to server, data is fetched and then template is applied   BUT SECOND  call will gennerate folllowing error   as reported by IE (other browsers simply do not show any acivity
"constructor is null or not an object"

looks like template is already applied and DIV are loaded with template data and now they are causing problems second tmie.


my template is given below
<script type="text/html" id="TemplateResultsTable">  
<table>

  <thead>

    <tr style="background-color:Maroon;color:White;">
      <th>Employee ID</th>
      <th>User Name</th>
      <th>First Name</th>
      <th>last Name</th>
    </tr>

  </thead>

  <tbody>

   {#foreach $T.Head as record}

    <tr>

      <td>{$T.record.id}</td>

      <td>{$T.record.username}</td>

      <td>{$T.record.firstname}</td>

      <td>{$T.record.lastname}</td>

    </tr>

    {#/for}

  </tbody>

</table>
</script>
        $(document).ready(
        function() 
        {
             $("#ddlDept").change(
             function() 
             {
                var DeptID = $("#ddlDept > option[@selected]").attr("text");
                var path;
                
                
                
                if (DeptID != 0) 
                {
                    path = FormatUrl('http://localhost:1453/PaggingDotNet/Ajax2/Handler.ashx');
                    
                    $.getJSON(path, 
                    function(employees) 
                    {
                        
                        var myobj;
                        myobj = null;
                        myobj = employees;
                        
                        
                        
                        //$("#dvDetails").setTemplate($("#TemplateResultsTable").html());
                        //$("#dvDetails").processTemplate(employees);
                                                
                        
                        
                        
                        var sss;
                        sss = "ID " + myobj.Head[0].id + "<br>";
                        sss = sss + "Name " + myobj.Head[0].firstname + " " + myobj.Head[0].lastname +  "<br>";
                        
                        sss = sss + "ID " + myobj.Head[1].id + "<br>";
                        sss = sss + "Name " + myobj.Head[1].firstname + " " + myobj.Head[1].lastname +  "<br>";
 
                        sss = sss + "ID " + myobj.Head[2].id + "<br>";
                        sss = sss + "Name " + myobj.Head[2].firstname + " " + myobj.Head[2].lastname +  "<br>";
                        
                        document.getElementById( 'dvDetails' ).innerHTML = '';                        
                        $("#dvDetails").html(sss);
                    });               
                }                
              });
              
         });
 
 
 
 
        function FormatUrl(url)
        {
            var newUrl = url;
            newUrl += '?ver=' + Math.random().toString();
            return newUrl;
        }

Open in new window

0
 
anoyesCommented:
Just an FYI, you can prevent caching w/o the use of random query strings by setting cache: false on the JQ $.ajax function.  You can't do that with $.getJSON, but since that is just a convenience function for $.ajax you could do the same thing as you have shown above like this, w/o the need to keep generating a random URL.  I'm looking into the jTemplate thing now...

        $(document).ready(
        function() 
        {
             $("#ddlDept").change(
             function() 
             {
                var DeptID = $("#ddlDept > option[@selected]").attr("text");
                var path;
                
                
                
                if (DeptID != 0) 
                {
                    path = 'http://localhost:1453/PaggingDotNet/Ajax2/Handler.ashx';
                    
                    $.ajax({
                    url: path,
                    dataType: 'json',
                    cache: false,
                    type: 'get',
                    success: function(employees) 
                    {
                        
                        var myobj;
                        myobj = null;
                        myobj = employees;
                        
                        
                        
                        //$("#dvDetails").setTemplate($("#TemplateResultsTable").html());
                        //$("#dvDetails").processTemplate(employees);
                                                
                        
                        
                        
                        var sss;
                        sss = "ID " + myobj.Head[0].id + "<br>";
                        sss = sss + "Name " + myobj.Head[0].firstname + " " + myobj.Head[0].lastname +  "<br>";
                        
                        sss = sss + "ID " + myobj.Head[1].id + "<br>";
                        sss = sss + "Name " + myobj.Head[1].firstname + " " + myobj.Head[1].lastname +  "<br>";
 
                        sss = sss + "ID " + myobj.Head[2].id + "<br>";
                        sss = sss + "Name " + myobj.Head[2].firstname + " " + myobj.Head[2].lastname +  "<br>";
                        
                        document.getElementById( 'dvDetails' ).innerHTML = '';                        
                        $("#dvDetails").html(sss);
                    });               
                }                
              });
              
         });

Open in new window

0
 
anoyesCommented:
OK, got it.  First of all forget about my code above - I missed a closing curly brace in there i think.  Anywho, your ASHX page was generating a JSON string with a trailing comma at the end of your records list, which IE doesn't like (http://blog.qoqoa.com/2006/04/18/trailing-comma-within-jsons-array/).  So, make sure that the Records array doesn't have any trailing commas, and the script below should take care of your caching issue.

    <script type="text/javascript">
        $(document).ready(
        function()
        {
            $("#ddlDept").change(
             function()
             {
                 var DeptID = $("#ddlDept > option:selected").attr("text");
                 var path;
 
                 if (DeptID != 0)
                 {
                     path = 'Handler.ashx';
                     $.ajax({
                         url: path,
                         type: 'get',
                         dataType: 'json',
                         cache: false,
                         success: function(employees) {
                             $("#dvDetails").setTemplate($("#TemplateResultsTable").html());
                             $("#dvDetails").processTemplate(employees);
                         }
                     });
                 }
             });
 
        });
    </script>

Open in new window

0
 
Michel PlungjanIT ExpertCommented:
Drat, I saw it and ignored it since the JSON editor was happy
0
 
shahzad73Author Commented:
alright you are right it worked       you owe me these points now     but if can look into this code also  because this code is also generating an error.  it calls the ajax first tmie correctly in all browsers and template is rendered correctly. but the second call reveals the following error.

constructor is null or not an object


this time i got a code    http://www.codeproject.com/KB/aspnet/ASPNET_DataTable_to_JSON.aspx    and function name is   CreateJsonParameters  


whole code is given below   any way i will give away the point

Server side code ASHX 
---------------------
 
<%@ WebHandler Language="C#" Class="Handler" %>
 
using System;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Text;
 
 
public class Handler : IHttpHandler {
    
    public void ProcessRequest (HttpContext context) 
    {
        context.Response.ContentType = "text/plain";
        //context.Response.ContentType = "application/json";
 
        DataTable dt = CreateDataTable();
 
        AddDataToTable("user name", "name 2", "last name", dt);
        AddDataToTable("user name 1", "name 3", "last name", dt);
        AddDataToTable("user name 2", "name 4", "last name", dt);
        AddDataToTable("user name 3", "name 5", "last name", dt);
        AddDataToTable("user name 4", "name 6", "last name", dt);
 
        context.Response.Write( CreateJsonParameters(dt) );
    }
    
    
 
    public bool IsReusable {
        get {
            return false;
        }
    }
 
 
 
 
 
 
 
 
 
 
    private DataTable CreateDataTable()
    {
        DataTable myDataTable = new DataTable();
 
        DataColumn myDataColumn;
 
        myDataColumn = new DataColumn();
        myDataColumn.DataType = Type.GetType("System.String");
        myDataColumn.ColumnName = "id";
        myDataTable.Columns.Add(myDataColumn);
 
        myDataColumn = new DataColumn();
        myDataColumn.DataType = Type.GetType("System.String");
        myDataColumn.ColumnName = "username";
        myDataTable.Columns.Add(myDataColumn);
 
        myDataColumn = new DataColumn();
        myDataColumn.DataType = Type.GetType("System.String");
        myDataColumn.ColumnName = "firstname";
        myDataTable.Columns.Add(myDataColumn);
 
        myDataColumn = new DataColumn();
        myDataColumn.DataType = Type.GetType("System.String");
        myDataColumn.ColumnName = "lastname";
        myDataTable.Columns.Add(myDataColumn);
 
        return myDataTable;
    }
 
 
 
 
    private void AddDataToTable(string username, string firstname, string lastname, DataTable myTable)
    {
        DataRow row;
 
        row = myTable.NewRow();
 
        row["id"] = Guid.NewGuid().ToString();
        row["username"] = username;
        row["firstname"] = firstname;
        row["lastname"] = lastname;
 
        myTable.Rows.Add(row);
    }
 
 
 
 
 
 
 
 
 
 
    public string CreateJsonParameters(DataTable dt)
    {
 
        /* /****************************************************************************
 
         * Without goingin to the depth of the functioning of this Method, i will try to give an overview
 
         * As soon as this method gets a DataTable it starts to convert it into JSON String,
 
         * it takes each row and in each row it grabs the cell name and its data.
 
         * This kind of JSON is very usefull when developer have to have Column name of the .
 
         * Values Can be Access on clien in this way. OBJ.HEAD[0].<ColumnName>
 
         * NOTE: One negative point. by this method user will not be able to call any cell by its index.
 
         * *************************************************************************/
 
        StringBuilder JsonString = new StringBuilder();
 
        //Exception Handling        
 
        if (dt != null && dt.Rows.Count > 0)
        {
 
            JsonString.Append("{ ");
 
            JsonString.Append("\"Head\":[ ");
 
            for (int i = 0; i < dt.Rows.Count; i++)
            {
 
                JsonString.Append("{ ");
 
                for (int j = 0; j < dt.Columns.Count; j++)
                {
 
                    if (j < dt.Columns.Count - 1)
                    {
 
                        JsonString.Append("\"" + dt.Columns[j].ColumnName.ToString() + "\":" + "\"" + dt.Rows[i][j].ToString() + "\",");
 
                    }
 
                    else if (j == dt.Columns.Count - 1)
                    {
 
                        JsonString.Append("\"" + dt.Columns[j].ColumnName.ToString() + "\":" + "\"" + dt.Rows[i][j].ToString() + "\"");
 
                    }
 
                }
 
                /*end Of String*/
 
                if (i == dt.Rows.Count - 1)
                {
 
                    JsonString.Append("} ");
 
                }
 
                else
                {
 
                    JsonString.Append("}, ");
 
                }
 
            }
 
            JsonString.Append("]}");
 
            return JsonString.ToString();
 
        }
 
        else
        {
 
 
 
            return null;
 
        }
 
    }
 
 
 
}
 
 
 
 
 
 
 
Javascript code
---------------
 
 
    <script type="text/javascript">
        $(document).ready(
        function()
        {
            $("#ddlDept").change(
             function()
             {
                 var DeptID = $("#ddlDept > option:selected").attr("text");
                 var path;
 
                 path = FormatUrl('http://localhost:1453/PaggingDotNet/Ajax2/Handler.ashx');
                 
                 if (DeptID != 0)
                 {
                     path = 'Handler.ashx';
                     $.ajax({
                         url: path,
                         type: 'get',
                         dataType: 'json',
                         cache: false,
                         success: function(employees) {
                             $("#dvDetails").setTemplate($("#TemplateResultsTable").html());
                             $("#dvDetails").processTemplate(employees);
                         }
                     });
                 }
             });
 
        });
        
        
        
 
        function FormatUrl(url)
        {
            var newUrl = url;
            newUrl += '?ver=' + Math.random().toString();
            return newUrl;
        }        
    </script>
 
 
 
 
 
 
jTemplate
----------
<script type="text/html" id="TemplateResultsTable">   
<table>
 
  <thead>
 
    <tr style="background-color:Maroon;color:White;">
      <th>Employee ID</th>
      <th>User Name</th>
      <th>First Name</th>
      <th>last Name</th>
    </tr>
 
  </thead>
 
  <tbody>
 
   {#foreach $T.Head as record}
 
    <tr>
 
      <td>{$T.record.id}</td>
 
      <td>{$T.record.username}</td>
 
      <td>{$T.record.firstname}</td>
 
      <td>{$T.record.lastname}</td>
 
    </tr>
 
    {#/for}
 
  </tbody>
 
</table>
</script>

Open in new window

0
 
anoyesCommented:
Hmmm weird I was pretty sure I had tried that and it was working...oh well.  I'll check it out and get back to you as soon as i have a chance.

-adam
0
 
shahzad73Author Commented:
anoyes    i will try to resolve the last problme if you can provide me any input that will be great
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 9
  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now