Jump to content


Photo

Ajax E Retorno De Função


  • Faça o login para participar
13 replies to this topic

#1 danielswx

danielswx

    Turista

  • Usuários
  • 27 posts
  • Sexo:Não informado

Posted 19/02/2006, 23:15

Amigos, estou quebrando a cabeça tentando tratar o retorno de uma função que utiliza XMLHttpRequest. Eis o código:

function ajaxRun(id,url){
  xmlhttp.open("GET",url,true);
  xmlhttp.onreadystatechange=function() {
    if (xmlhttp.readyState==4) {
      if (xmlhttp.status == 200) {
        $(id).innerHTML=xmlhttp.responseText;
        if (xmlhttp.responseText.match("<!--###")) {
          results = xmlhttp.responseText.split("###");
          alert(results[1]);
        }
      } else {
        alert(xmlhttp.statusText);
        window.location.reload();
      }
    }
  }
  xmlhttp.send(null);
  if (typeof(results[1]) != "undefined") {
    return results[1];
  } else {
    return 0;	
  }
}

Essa função utiliza XMLHttpRequest para processar um script que faz uma consulta SQL, e caso haja erro a saída seria algo como:
<script><!--###mensagem de erro!###--></script>
Assim, utilizo a função "match" para checar se houve erro e exibi-la através de um "alert". Além disso preciso tratar o retorno da função, pois caso não exista mensagem preciso saber para, com uma outra função, executar outros comandos caso a consulta tenha sucesso.
Depois de enviar o conteúdo através da função "send" do objeto XMLHttpRequest, faço o teste do valor de "typeof(results[1])", onde results[1] deveria conter a mensagem de erro. Caso seja "undefined" retorna 0, do contrário retorna a mensagem de erro.
Aí temos o problema! Se houver erro na consulta SQL o valor "typeof(results[1])" deveria ser "string", mas neste caso está retornando "undefined". Mas como se não bastasse esse problema, descobri que se eu mostrar o valor de "typeof(results[1])" através de um "alert" antes de testá-lo tudo funciona perfeitamente, isto é, results[1] é uma string.
Desde então tenho quebrado a cabeça há dois dias.
Algum sábio programador teria solução para isso?

[]s
Daniel

#2 Tarkan

Tarkan

    Powered by Linux - Que inglês! ;)

  • Ex-Admins
  • 651 posts
  • Sexo:Masculino
  • Localidade:Copacabana - RJ

Posted 20/02/2006, 08:29

Experimenta mudar o modo da função para síncrona, para ver se resolve.
Na linha:

xmlhttp.open("GET",url,true);

Troque para:

xmlhttp.open("GET",url,false);

Se não resolver, a gente pensa em outro meio...
Abraços!

:D
' nome: gustavo veiga
' profissão: ALOG Data Centers do Brasil (analista de sistemas)
' publicidade: ALOG Data Centers do Brasil

#3 danielswx

danielswx

    Turista

  • Usuários
  • 27 posts
  • Sexo:Não informado

Posted 21/02/2006, 02:27

Tarkan, síncrona não funciona....

#4 Klaus

Klaus

    @ ubuntu jaunty

  • Ex-Admins
  • 7924 posts
  • Sexo:Masculino
  • Localidade:127.0.0.1

Posted 21/02/2006, 14:06

O que você acha de retornar simplesmente "erro"?

Assim, é só comparar o responseText com "erro".
Klaus Paiva
Conheça também: Taperás

#5 danielswx

danielswx

    Turista

  • Usuários
  • 27 posts
  • Sexo:Não informado

Posted 21/02/2006, 16:42

Klaus, não entendi. Como ficaria então pra pegar a mensagem de erro que está em results[1]?

#6 Klaus

Klaus

    @ ubuntu jaunty

  • Ex-Admins
  • 7924 posts
  • Sexo:Masculino
  • Localidade:127.0.0.1

Posted 22/02/2006, 11:21

Retorne assim então:

erro|Aqui depois do pipe sua mensagem...
Klaus Paiva
Conheça também: Taperás

#7 danielswx

danielswx

    Turista

  • Usuários
  • 27 posts
  • Sexo:Não informado

Posted 22/02/2006, 12:16

Klaus, acho que você não entendeu (ou eu não entendi sua resposta). O problema é que quando chamo a função pela primeira vez, "typeof(results[1])" não tem o valor que deveria ter (uma string, a mensagem de erro) retornando "undefined". Mas como disse, descobri que se eu mostrar o valor de "typeof(results[1])" através de um "alert" antes de testá-lo tudo funciona perfeitamente, isto é, results[1] é uma string.
Tem explicação isso?
Entendeu o problema?

[]s
Daniel

#8 Klaus

Klaus

    @ ubuntu jaunty

  • Ex-Admins
  • 7924 posts
  • Sexo:Masculino
  • Localidade:127.0.0.1

Posted 22/02/2006, 15:54

Bom, agora que li seu código por completo entendi seu real problema. Achei que fosse outro! :D

function ajaxRun(id,url){
xmlhttp.open("GET",url,true);
xmlhttp.onreadystatechange=function() {
  if (xmlhttp.readyState==4) {
    if (xmlhttp.status == 200) {
      $(id).innerHTML=xmlhttp.responseText;
      if (xmlhttp.responseText.match("<!--###")) {
        results = xmlhttp.responseText.split("###");
        alert(results[1]);
      }
    } else {
      alert(xmlhttp.statusText);
      window.location.reload();
    }

  }
}
xmlhttp.send(null);
if (typeof(results[1]) != "undefined") {
  return results[1];
} else {
  return 0;
}

}


Faça uns testes mas, na minha visão sem testar, acho que o código em azul está sendo executado antes do código em vermelho, daí o problema.
Klaus Paiva
Conheça também: Taperás

#9 danielswx

danielswx

    Turista

  • Usuários
  • 27 posts
  • Sexo:Não informado

Posted 22/02/2006, 17:53

Klaus, mas como posso fazer difrerente? Já tentei várias coisas aqui e tudo dá na mesma! Na primeira vez que chamo a função não funciona corretamente mas na segunda funciona... A função "ajaxRun" está associada a um botão, quando clico a primeira vez não funciona, mas se tentar uma segunda vez funciona! Acontece que nas duas vezes o conteúdo do script é processado mas só retorna da forma correta na segunda vez.... Sinceramente, não consigo entender o que acontece... três dias batendo cabeça... já estou quase pagando alguém pra resolver isso!!!!

#10 Klaus

Klaus

    @ ubuntu jaunty

  • Ex-Admins
  • 7924 posts
  • Sexo:Masculino
  • Localidade:127.0.0.1

Posted 22/02/2006, 18:29

function ajaxRun(id,url){
xmlhttp.open("GET",url,true);
xmlhttp.onreadystatechange=function() {
  if (xmlhttp.readyState==4) {
    if (xmlhttp.status == 200) {
      $(id).innerHTML=xmlhttp.responseText;
      if (xmlhttp.responseText.match("<!--###")) {
        results = xmlhttp.responseText.split("###");
        //alert(results[1]);
        if (typeof(results[1]) != "undefined") {
          alert( results[1] );
        } else {
          alert( 0 );
        }

      }
    } else {
      alert(xmlhttp.statusText);
      window.location.reload();
    }
  }
}
xmlhttp.send(null);
}


PS: Função $ rulez! :D
Klaus Paiva
Conheça também: Taperás

#11 danielswx

danielswx

    Turista

  • Usuários
  • 27 posts
  • Sexo:Não informado

Posted 22/02/2006, 19:35

Ok, isso aí dá certo! O problema é preciso retornar algum valor. Entendeu? Caso haja erro, mostra a mensagem e tudo bem... Mas se não houver, preciso saber para executar outras rotinas. Isto é, a função ajaxRun tem que retornar alguma coisa. É aí que tá o problema... Na primeira vez retorna errado e na segunda correto!
Preciso testar de alguma forma se deu certo ou não, se há mensagem de erro ou não e, para isso, preciso retornar algum valor...

Amigo, nunca tinha me deparado com algo assim. O problema é que nem consigo pensar numa alternativa. Eu preciso, na verdade, é interagir com o usuário caso haja erro ou não, tipo perguntar se ele quer inserir um novo registro ou algo parecido, mas isso é só um exemplo, precisarei fazer outras coisas também. É por isso que é importante que a função retorne algum valor.

Agora eu te pergunto, quando executo o bloco em "xmlhttp.onreadystatechange" tem como retornar algum valor? Como atrbuí-lo a uma variável?
Já tentei, por exemplo, separar essa função fazendo com que ele retorne um valor e depois atribui a função assim:
xmlhttp.onreadystatechange = funcao;
Mas ficou no mesmo, na primeira vez retorna errado, mas na segunda retorna correto!

[]s
Daniel

#12 Klaus

Klaus

    @ ubuntu jaunty

  • Ex-Admins
  • 7924 posts
  • Sexo:Masculino
  • Localidade:127.0.0.1

Posted 23/02/2006, 10:43

Já me deparei com este problema também. :D O problema é que o readystatechange é um evento que é disparado várias vezes! No mínimo 4, no IE e Firefox.

Ou seja, quando ele é executado no estado que você quer (4), a função ajaxRun já saiu do fluxo de execução do navegador. :D

Pro problema que tive, a solução foi chamar uma função simples com um parâmetro que seria o retorno e, daí daria sequência as demais funções. Exemplo: (suponha que este código está dentro do onreadystatechange, no status 4 e resposta do servidor 200)

if( resultadoValido )
{
  prossegueAJAX( results[1], id, url );
}
else
{
  prossegueAJAX( 0, id, url );
}


Daí uma função hipotética prossegueAJAX:

function prossegueAJAX( status, id, url )
{

  if ( status )
  {
    // deu certo...
  }
  else
  {
    // ou deu errado
  }

}


No problema que eu tive, eu precisava guardar variáveis como você também precisa no onreadystatechange. Daí eu criei a seguinte função:

'processaAJAX' : function ( ajaxUOL, aid, pagina, tipo, id, valor ) {

  if ( ajaxUOL.readyState == 4 ) {
 
  var resposta = dux.capturaValor ( ajaxUOL.responseXML, "codigo" );
 
  if ( !resposta ) {
    dux.respostaInvalida ( aid );
  }
   
  dux.acaoAJAX ( ajaxUOL.responseXML, aid, pagina, tipo, id, valor, resposta );
 
  }

},


dux é o nome do meu objeto, por isso você vai ver ele bastante pelo código. :D

Essa função eu chamo no onreadystatechange e, dentro dela você pode reparar que eu parto para outro método (dux.acaoAJAX), que é uma ação baseada na resposta do servidor. Bom, qualquer coisa dá um toque que eu explico melhor alguma parte...
Klaus Paiva
Conheça também: Taperás

#13 danielswx

danielswx

    Turista

  • Usuários
  • 27 posts
  • Sexo:Não informado

Posted 23/02/2006, 13:50

Klaus, meu amigo, você salvou minha vida! :D

A única diferença do que você fez para o que eu fiz é que tenho vários parmetros diferentes para as funções que presciso usar, e como não vão ser poucas, jogos eles dentro de array e lá no onreadystatechange verifico esses parametros para chamar a função correta e executar o que eu quero...

Muito obrigado pela ajuda!

[]s
Daniel

#14 Klaus

Klaus

    @ ubuntu jaunty

  • Ex-Admins
  • 7924 posts
  • Sexo:Masculino
  • Localidade:127.0.0.1

Posted 23/02/2006, 14:03

:D Legal.

[]'s
Klaus Paiva
Conheça também: Taperás




1 user(s) are reading this topic

0 membro(s), 1 visitante(s) e 0 membros anônimo(s)

IPB Skin By Virteq