2017-09-24 4 views
0

Je fais une requête API via JSONP afin d'éviter les erreurs inter-domaines. Je veux stocker la réponse dans une variable qui est dans une fermeture (une expression de la fonction "module"), qui est accessible via deux "méthodes publiques".Impossible de stocker la réponse JSONP dans une fermeture

L'une de ces méthodes, module.store, est le rappel utilisé par la réponse de l'API. L'autre méthode met à jour la balise p avec le contenu de la réponse de l'API. Après avoir cliqué sur "soumettre" pour lancer la demande d'API, je sais que le rappel est appelé avec succès, car je peux voir brièvement l'affichage mis à jour avant qu'il ne disparaisse.

Je pense que je dois perdre la réponse une fois que la fonction se termine, mais la fermeture devrait toujours pouvoir accéder à la variable privée.

Si j'appelle le requestJSONP() depuis le navigateur, cela fonctionne.

Je suis incapable de recréer le problème dans le violon JS car il n'aime pas la demande JSONP.

HTML:

<body> 
<header>Wikipedia Viewer</header> 
<section> 
    <div class="container"> 
     <p>default text</p> 
     <form> 
      <button>Submit</button> 
     </form> 
    </div> 
</section> 
</body> 

JS:

document.addEventListener('DOMContentLoaded', addListenerToButton); 

//callback for DOM load which adds a click event on the submit button 
function addListenerToButton() { 

var button = document.getElementsByTagName("button")[0]; 

button.addEventListener("click", requestJSONP); 
console.log("addListenerToButton"); 
}; 

//advoids cross browser origin error 
function requestJSONP(searchTerm) { 
    //dynamically create a script tag 
    var scriptTag = document.createElement("script"); 
    //set url 
    scriptTag.src = "https://en.wikipedia.org/w/api.php?action=opensearch&search=covfefe&limit=10&namespace=0&format=json&callback=test"; 
    //append tag to head element 
    document.getElementsByTagName("head")[0].appendChild(scriptTag); 
    console.log("got to JSONP"); 
}; 

function test(data){ 
     module.store(data); 
} 

//callback invoked when API sends reponse 
var module = (function(){ 
    var storedValue = []; 
console.log("got to module"); 
    return { 
     store: function(val){ 
      storedValue.push(val); 
      console.log("got to module.store"); 
      displayArray(); 
     }, 

     retrieve: function(){ 
      return storedValue; 
     }, 

    } 

}()); 

function displayArray(){ 
    var stored = module.retrieve(); 
    pTag = document.getElementsByTagName("p")[0]; 
    text = pTag.textContent = stored; 

}  
+1

jsonp est appelé à partir d'un contexte frais/global, il n'y a pas de fermeture impliquée ... – dandavis

Répondre

0

Le comportement par défaut (dans Chrome au moins) est de rafraîchir la page, qui défrichait valeur stockée. J'ai remplacé ce comportement par défaut ci-dessous:

function saveText(event) { 
    debugger 
    event.preventDefault() 
    var userInput = document.getElementsByTagName("input")[0].value; 

    if (userInput === "") { 
     alert("Please enter a search term") 
     return 
    } 
    requestJSONP(userInput); 
    console.log("saveText"); 
};