-1

I have this javascript function that gets called when the search button is pressed. it fetches json from a Flask server. Then its supposed to parse it with JSON.parse(data)

function search(){
   var  searchTerm = document.getElementById("songname").value
   if(searchTerm === "" == false){

     fetch(`/searchq=${searchTerm}`, {
        method: "GET"
     }).then((response) => {
    return response.json()
     }).then(function (data) {
       result = JSON.parse(data)
    
     //Doesnt work
     for (var i in result) {

        console.log(result[i], i)
     }


  })
 }
}

but when i loop over the result, it just outputs every single character instead of every key, value pair.

davidism
  • 121,510
  • 29
  • 395
  • 339

1 Answers1

0

The main problem in your code is that you're calling JSON.parse on something that isn't a string. response.json() reads teh body of the response and parses it, so data in the second fulfillment handler is already the parsed structure. Just remove the JSON.parse and use data directly.

There are a couple of other issues: You need to check for HTTP success (fetch only rejects its promise on network errors, a footgun in the API I write about here), and you need to handle errors.

Something like this:

function search() {
    var searchTerm = document.getElementById("songname").value;
    if (searchTerm === "" == false) {
        fetch(`/searchq=${searchTerm}`, {
            method: "GET"
        })
        .then((response) => {
            // Check for HTTP success
            if (!response.ok) {
                throw new Error(`HTTP error ${response.status}`);
            }
            // Read and parse the JSON
            return response.json()
        })
        .then(function (data) {
            for (var i in data) {     // Note this is for looping an **object**'s
                                      // properties, not an array
                console.log(data[i], i);
            }
        })
        .catch(error => {
            // ...handle/report error...
        });
    }
}

If you still have trouble working with data, I suggest reading the answers to these questions:

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I tried removing the `JSON.parse` like you said and looped over `data` but it still console.logs every character. – user15385715 Apr 12 '21 at 07:41
  • This is the `data` without `JSON.parse` : `"{'P2': 'get-song-redirect_name=P2', 'She Never Been To Pluto': 'get-song-redirect_name=She Never Been To Pluto', 'NAVUZIMETRO#PT2': 'get-song-redirect_name=NAVUZIMETRO#PT2', 'Free Lighter (feat. Lil Uzi Vert & Chief Keef)': 'get-song-redirect_name=Free Lighter (feat. Lil Uzi Vert & Chief Keef)', 'Can@apst Lose': 'get-song-redirect_name=Can@apst Lose', 'Guap Like Uzi': 'get-song-redirect_name=Guap Like Uzi'}"` – user15385715 Apr 12 '21 at 07:42
  • thanks for the links ill try the new code and see if it works. – user15385715 Apr 12 '21 at 07:44
  • @ireallyhatestackoverflow - It looks like the API you're calling is sending back a very strange structure. What it's sending back is clearly JSON (otherwise `response.json()` would throw an error), but it would appear to be JSON for a string, and then the string is in the format you've shown above, which is not JSON. At the API end, someone is apparently taking a string and passing it through that language's version of `JSON.stringify` (`json_encode` in PHP for instance). With the corrected client-side code above, the remaining problem is at the server end. – T.J. Crowder Apr 12 '21 at 07:45
  • I dont know if you're familiar with the [Flask python framework](https://flask.palletsprojects.com/) which is what im using for the backend. And what im returning is `jsonify(f"\"{response_dict}\"")` – user15385715 Apr 12 '21 at 07:47
  • So im adding the quotes myself, is that wrong? – user15385715 Apr 12 '21 at 07:49
  • turns out it was a problem with the backend and this new js fixed the front end. – user15385715 Apr 12 '21 at 08:15