Unable to load XML file

Hi all,

I'm trying to allow the user the enter a postcode and then retrieve the list of properties in the area with the Zoopla api. Unfortunately, I get the following error on line 51 and 59, any ideas?

TypeError: xml is undefined[Learn More]

It's working fine in Processing.

Thanks in advance, Charles

var xml, postInput, postButton, myDiv, cnv, postCode;
var running;

function setup() {

    running = false;

    cnv = createCanvas(windowWidth * 0.1, windowHeight / 2);
    var y = (windowHeight / 2) - 25;
    cnv.position(10, y);
    cnv.style("z-index", "-1")
    textAlign(CENTER);
    textSize(16);

    myDiv = createDiv("Property Analyser");
    myDiv.position((windowWidth / 2) - 100, windowHeight * 0.40);
    myDiv.style("font-size", "24px");
    myDiv.style("color", "#FFFFFF");
    myDiv.style("z-index", "2")

    postInput = createInput();
    postInput.position(windowWidth * 0.5 - (windowWidth * 0.1), windowHeight * 0.5);
    postInput.style("z-index", "2")
    postInput.size(windowWidth * 0.2, windowHeight * 0.05);

    postButton = createButton('Input Postcode');
    postButton.size(windowWidth * 0.1, windowHeight * 0.04);
    postButton.position(windowWidth * 0.5 - windowWidth * 0.05, windowHeight * 0.57);
    postButton.mousePressed(next);
    postButton.style("z-index", "2")

}

function draw() {

    if (running) {
        background(255);
    }
}

function next() {
    postCode = postInput.value();
    postButton.style("visibility", "hidden");
    postInput.style("visibility", "hidden");
    myDiv.style("z-index", "-1");
    cnv.style("z-index", "1")
    running = true;

    console.log(postCode);
    var url = "http://api.zoopla.co.uk/api/v1/property_listings.xml?postcode=" + postCode + "&api_key=bmm77zppverakbnfnmtyuky3";
    xml = loadXML(url, printHouses(), message());
}

function message(message){
    console.log(message);
}

function printHouses(){
    var listings = xml.getChildren("listing");

    for (var i = 0; i < listings.length; i++) {
        var listing = listings[i].getChild("agent_address");
            console.log(listing.getContent());
    }
}

Answers

  • edited January 2017

    http://p5js.org/reference/#/p5/loadXML

    @ line #51 xml = loadXML(url, printHouses(), message());

    You're passing undefined as argument for both success & error callbacks! :-SS
    All functions finishing w/o return implicitly result in undefined btW.

    You're supposed to pass the reference for a function for the callback parameters.
    Instead you're invoking them w/ (): :-\"

    xml = loadXML(url, printHouses, message);

  • edited January 2017

    That seems be a step in the right direction however the error message function gets executed and prints the following message:

        XMLHttpRequest { onreadystatechange: [27]</</noop(), readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, responseURL: "", status: 0, statusText: "", responseType: "", response: "" }
        Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://api.zoopla.co.uk/api/v1/property_listings.xml?postcode=ip12&api_key=bmm77zppverakbnfnmtyuky3. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
    

    After checking with the with the Zoopla reference it doesn't seems to make much sense. Furthermore the data gets received fine when entered in the browser.

    Here's the updated code:

    var xml, postInput, postButton, myDiv, cnv, postCode;
    var running;
    
    
    function setup() {
    
        running = false;
    
        cnv = createCanvas(windowWidth * 0.1, windowHeight / 2);
        var y = (windowHeight / 2) - 25;
        cnv.position(10, y);
        cnv.style("z-index", "-1")
        textAlign(CENTER);
        textSize(16);
    
        myDiv = createDiv("Property Analyser");
        myDiv.position((windowWidth / 2) - 100, windowHeight * 0.40);
        myDiv.style("font-size", "24px");
        myDiv.style("color", "#FFFFFF");
        myDiv.style("z-index", "2")
    
        postInput = createInput();
        postInput.position(windowWidth * 0.5 - (windowWidth * 0.1), windowHeight * 0.5);
        postInput.style("z-index", "2")
        postInput.size(windowWidth * 0.2, windowHeight * 0.05);
        postButton = createButton('Input Postcode');
        postButton.size(windowWidth * 0.1, windowHeight * 0.04);
        postButton.position(windowWidth * 0.5 - windowWidth * 0.05, windowHeight * 0.57);
        postButton.mousePressed(next);
        postButton.style("z-index", "2")
    
    }
    
    function draw() {
    
        if (running) {
            background(255);
    
    
        } else {
    
        }
    
    }
    
    function next() {
        postCode = postInput.value();
        postButton.style("visibility", "hidden");
        postInput.style("visibility", "hidden");
        myDiv.style("z-index", "-1");
        cnv.style("z-index", "1")
        running = true;
    
        console.log(postCode);
        var xml = "http://api.zoopla.co.uk/api/v1/property_listings.xml?postcode=" + postCode + "&api_key=bmm77zppverakbnfnmtyuky3";
        xml = loadXML(xml, printHouses, error);
    }
    
    function error(message){
        console.log(message);
        return
    }
    
    function printHouses(print){
           var listings = print.getChildren("listing");
    
        for (var i = 0; i < listings.length; i++) {
            var listing = listings[i].getChild("agent_address");
            console.log(listing.getContent());
        }
        return
    }
    
    function initMap() {
        var uluru = {
            lat: 53.441456,
            lng: -15.783257
        };
        var map = new google.maps.Map(document.getElementById('map'), {
            zoom: 5,
            center: uluru
        });
    }
    
  • edited January 2017

    Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://api.Zoopla.co.uk/api/v1/property_listings.xml?postcode=ip12&api_key=bmm77zppverakbnfnmtyuky3

    1st, make sure you're running your code under a server (be it local or remote):
    https://GitHub.com/processing/p5.js/wiki/Local-server

    Or if you prefer, just use some Firefox-based browser in order to run it instead. *-:)
    If you still got CORS exception for it, loadXML() alone can't do anything for you anymore. :(

    Your last options would be to request the site's admin to authorize CORS for you.
    Or hack your way thru' via some CORS proxy site, like http://CrossOrigin.me for example. :ar!

    For further details, read old forum threads about it: :-B
    https://forum.Processing.org/two/discussions/tagged/cors

  • edited January 2017

    Thanks for your help but I'm not having much success.

    • I'm using firefox
    • CrossOrigin doesn't return anything
    • Created a server with Node.js: still get the "Cross-Origin Request Blocked" error
    • Just posted on their forum but they don't look very active
  • edited January 2017

    Indeed your Zoopla site is denying CORS. Thus we can't load the ".xml" file from it. :-&
    I've even tried http://CrossOrigin.me as a CORS proxy for it; but it didn't work out either: :(

    http://p5ide.HerokuApp.com/editor#?sketch=5873a448c6a3ab040078c16d
    https://GitHub.com/technoboy10/crossorigin.me/issues/71

    /**
     * loadXML() from Zoopla via CORS Proxy (v1.0)
     * GoToLoop (2017-Jan-09)
     * 
     * forum.Processing.org/two/discussion/20149/unable-to-load-xml-file#Item_6
     * p5ide.HerokuApp.com/editor#?sketch=5873a448c6a3ab040078c16d
     */
    
    "use strict";
    
    const HTTP = 'http:' + '//',
          PROX = 'CrossOrigin.me/',
          SITE = 'api.Zoopla.co.uk/',
          PATH = 'api/v1/',
          FILE = 'property_listings.xml',
          QRY  = '?postcode=' + 'ip12',
          KEY  = '&api_key=' + 'bmm77zppverakbnfnmtyuky3',
          URI  = HTTP + PROX + HTTP + SITE + PATH + FILE + QRY + KEY;
    
    let xml;
    
    function preload() {
      console.log(URI);
      xml = loadXML(URI);
    }
    
    function setup() {
      console.log(xml);
    }
    
  • Thanks for your perseverance GoToLoop I've just sent them an email.

    Will update this post when I've found the solution :)

  • edited January 2017

    Got good news! Changed CORS proxy. B-)
    From http://CrossOrigin.me/ to http://CORS-Anywhere.HerokuApp.com/.
    And now it's working! <:-P

    Seems like some extra protections from the former were getting in the way somehow. 8-|
    But real fix is for the non-CORS site to activate CORS for its ".xml" files; so no need for proxy hacks. :ar!

    http://CodePen.io/GoSubRoutine/pen/Qdjmrm/top/?editors=0012

    /**
     * loadXML() from Zoopla via CORS Proxy (v2.0)
     * GoToLoop (2017-Jan-09)
     * 
     * forum.Processing.org/two/discussion/20149/unable-to-load-xml-file#Item_8
     * CodePen.io/GoSubRoutine/pen/Qdjmrm/top/?editors=0012
     *
     * api.Zoopla.co.uk/api/v1/property_listings.xml
     * ?postcode=ip12&api_key=bmm77zppverakbnfnmtyuky3
     */
    
    "use strict";
    
    const HTTP = 'http:' + '//',
          PROX = 'CORS-Anywhere.HerokuApp.com/',
          SITE = 'api.Zoopla.co.uk/',
          PATH = 'api/v1/',
          FILE = 'property_listings.xml',
          QRY  = '?postcode=' + 'ip12',
          KEY  = '&api_key=' + 'bmm77zppverakbnfnmtyuky3',
          URI  = HTTP + PROX + HTTP + SITE + PATH + FILE + QRY + KEY;
    
    let xml;
    
    function preload() {
      console.warn(URI);
      xml = loadXML(URI);
    }
    
    function setup() {
      console.log(xml);
      printHouseAddresses(xml);
    }
    
    function printHouseAddresses(district) {
      for (let listing of district.getChildren('listing')) {
        const address = listing.getChild('agent_address').getContent();
        console.info(address);
      }
    }
    
  • Incredible! :o

    Thank you very much!

    Ps: What's the purpose of "use strict"; ?

Sign In or Register to comment.