0

I am using the following function as middleware and want to send the length of the array (req.session.songArray.length) as a JSON however any JSON I attempt to send through res gives the error below. I understand that circular objects cannot be JSON stringified but just trying to use { num: 20 } gives this error and I am not sure why. When I remove the res.status.json line the code runs without errors. I am using npm packages genius-lyrics and express-session for insight.

async function initSongArray(req, res, next){
    const searches = await Client.songs.search(req.params.artist);
    let songNum = 0
    while((searches[songNum].artist.name.includes('&')) && req.params.and === 0){
        console.log("& detected")
        songNum++;
    }
    req.session.artist = searches[songNum].artist;
    req.session.songArray = await req.session.artist.songs({sort: 'popularity', perPage: 20, page: 1});
    req.session.currPage = 2
    console.log(req.session.songArray.length)
    res.status(200).json( { num: 20 } )
}

app.get('/artist/:artist/:and', initSongArray)

C:\Users\bgrie\Desktop\a\compsci.websites\typesiteNode\node_modules\express-session\index.js:598 var str = JSON.stringify(sess, function (key, val) { ^

TypeError: Converting circular structure to JSON --> starting at object with constructor 'Client' | property 'songs' -> object with constructor 'SongsClient' --- property 'client' closes the circle at JSON.stringify () at hash (C:\Users\bgrie\Desktop\a\compsci.websites\typesiteNode\node_modules\express-session\index.js:598:18) at isModified (C:\Users\bgrie\Desktop\a\compsci.websites\typesiteNode\node_modules\express-session\index.js:426:57) at shouldSave (C:\Users\bgrie\Desktop\a\compsci.websites\typesiteNode\node_modules\express-session\index.js:448:11) at ServerResponse.end (C:\Users\bgrie\Desktop\a\compsci.websites\typesiteNode\node_modules\express-session\index.js:334:11) at ServerResponse.send (C:\Users\bgrie\Desktop\a\compsci.websites\typesiteNode\node_modules\express\lib\response.js:232:10) at ServerResponse.json (C:\Users\bgrie\Desktop\a\compsci.websites\typesiteNode\node_modules\express\lib\response.js:278:15) at initSongArray (C:\Users\bgrie\Desktop\a\compsci.websites\typesiteNode\index.js:70:21) at processTicksAndRejections (node:internal/process/task_queues:96:5)

ben
  • 28
  • 5
  • If it's the `res.status(200).json(...)` that causes the error, it seems that the error should be reproducible if you remove all other lines of code from your function. Is that true? – Simon MᶜKenzie Aug 27 '22 at 20:38
  • @SimonMᶜKenzie yes, if I remove the rest of the code the line runs without errors so must be something changing res in some way? – ben Aug 27 '22 at 20:50
  • 1
    ```req.session.songArray = await req.session.artist.songs({sort: 'popularity', perPage: 20, page: 1});``` what happens when you remove this line? – Lord Bee Aug 27 '22 at 20:58
  • @LordBee you're pretty much correct, its the req.session.artist = searches[songNum].artist; that causes the error. Any idea what the issue is? – ben Aug 27 '22 at 21:06
  • @LordBee just to add, I had this code running previously except with local variables instead of req.session 's so it shouldn't have any issues with promises or anything I'm pretty sure – ben Aug 27 '22 at 21:08
  • The session is trying to serialize its data into JSON in order to save it to the session store. So, you're trying to put something in the session that has a circular reference in it and thus can't be serialized that way. So, apparently, `searches[songNum].artist` is not just a simple object. It must have references to other objects that then create a circular reference. I'd dive into what is in `searches[songNum].artist` and maybe construct a new object that only has a few properties in it that you need. – jfriend00 Aug 27 '22 at 21:13
  • @jfriend00 that makes a lot of sense, I see why the errors were thrown now. Thanks so much for the advice, I'll try stripping down the JSON to what's necessary and see if I can get that to function correctly without circular reference. – ben Aug 27 '22 at 21:23

1 Answers1

1

The session is trying to serialize its data into JSON in order to save it to the session store. So, you're trying to put something in the session that has a circular reference in it and thus can't be serialized that way. So, apparently, searches[songNum].artist is not just a simple object. It must have references to other objects that then create a circular reference.

I'd suggest you create a new object and assign just a few simple properties from searches[songNum].artist that you actually need in the session.

Probably searches[songNum].artist has some database stuff in it. If your database has a .toObject() method or something like that, it may be useful to turn it into a plain object.

jfriend00
  • 683,504
  • 96
  • 985
  • 979