pietroppeter / nimib

nimib 🐳 - nim 👑 driven ⛵ publishing ✍
https://pietroppeter.github.io/nimib/
MIT License
183 stars 10 forks source link

KaraxInstance null in kajax callback #249

Closed chancyk closed 3 weeks ago

chancyk commented 3 weeks ago

The redraw that's ultimately called in the line below receives a null KaraxInstance for some reason under Nimib.

https://github.com/karaxnim/karax/blob/master/karax/kajax.nim#L75

I've tried this with Nim 2.0.8 and Nim 2.2.0. It doesn't seem to be an issue with Karax because the ajax example in their repo works fine.

HugoGranstrom commented 3 weeks ago

Thanks for letting us know 😄 I don't think I ever tried Kajax when developing the Karax support in nimib so it might never have worked. I'll have a look during the week 👍

HugoGranstrom commented 3 weeks ago

Do you have a reproducible example by any chance?

chancyk commented 3 weeks ago

Give this a try:

import nimib

nbInit

nbKaraxCode:
    import karax/kajax

    proc handleRatesResponse(httpStatus: int, response: cstring) =
        echo response

    proc requestData() =
        let url = "https://jsonplaceholder.typicode.com/todos/1".cstring
        let headers = @[("Accept".cstring, "application/json".cstring)]
        ajaxGet(url, headers,
            cont=proc(httpStatus: int, response: cstring) = handleRatesResponse(httpStatus, response)
        )

    requestData()
    karaxHtml:
        text "Hello, World"

nbSave
chancyk commented 3 weeks ago

It seems like it's just trying to lift the global kxi KaraxInstance from the parent scope as a parameter default, but maybe there is something weird going on there because of the macros.

HugoGranstrom commented 3 weeks ago

Thanks, yes you are right:

proc ajaxGet*(url: cstring; headers: openarray[(cstring, cstring)];
          cont: proc (httpStatus: int, response: cstring);
          doRedraw: bool = true,
          kxi: KaraxInstance = kxi) =
  ajax("GET", url, headers, nil, cont, doRedraw, kxi)

What we do to allow multiple Karax apps to run at the same time is that we pass a custom kxiname for each one like this:

nim js -d:danger -d:kxiname=nimib_kxi_1 file.nim

So it will not find it in this case because it explicitly is looking for kxi and not our custom nimib_kxi_1

HugoGranstrom commented 3 weeks ago

Huh, but it seems Karax should handle that correctly :O https://github.com/karaxnim/karax/blob/2536062b7c2ffc031c70b9b92216b771a1206f98/karax/karax.nim#L60

HugoGranstrom commented 3 weeks ago

Aha! Moving the Kajax logic below the karaxHtml seems to work!

I think it has to do with Karax not being initialized before the setRenderer which is called at the end of karaxHtml

chancyk commented 3 weeks ago

Hmm, how so? I get a compile error from the requestData under karaxHtml because it's trying to treat it as a VNode in the buildHtml macro I think.

HugoGranstrom commented 3 weeks ago

Ahh, I was a bit unclear. I meant this:

import nimib

nbInit

nbKaraxCode:
    import karax/kajax

    proc handleRatesResponse(httpStatus: int, response: cstring) =
        echo response

    proc requestData() =
        let url = "https://jsonplaceholder.typicode.com/todos/1".cstring
        let headers = @[("Accept".cstring, "application/json".cstring)]
        ajaxGet(url, headers,
            cont=proc(httpStatus: int, response: cstring) = handleRatesResponse(httpStatus, response)
        )

    karaxHtml:
        text "Hello, World"

    requestData()

nbSave
HugoGranstrom commented 3 weeks ago

"After" karaxHtml would have been a better word than "under".

chancyk commented 3 weeks ago

Oh, duh! :) Reading the code, apparently there's also a postRender hook that seems to work for me as well!

HugoGranstrom commented 3 weeks ago

Yes postRender is basically a onKaraxLoad event handler if that makes sense. It will run everytime it renders though I think. I tried putting requestData() inside it and it seemed to be in an inifite loop

HugoGranstrom commented 3 weeks ago

Yep it runs every time Karax renders the page (for example when updating a variable used in the karaxHtml. So I'm not sure how useful it is for this case.

HugoGranstrom commented 3 weeks ago

If you want to fetch data periodically the example I showed in the NimConf video could be useful: https://github.com/nimib-land/nimconf24/blob/7a8a2b264f5b718f4fa8029da4a999aba8347431/nimib_intro.nim#L43-L54

chancyk commented 3 weeks ago

If you want to fetch data periodically the example I showed in the NimConf video could be useful: https://github.com/nimib-land/nimconf24/blob/7a8a2b264f5b718f4fa8029da4a999aba8347431/nimib_intro.nim#L43-L54

That's useful, thanks!

I was just trying to initialize some data, so your first solution seems to be working fine. I appreciate the help! : )