Hello helpers! I am working on a Object Oriented Trello API at the moment. However, I stumbled upon a huge obstacle, which might make it impossible, however, I am not sure.
Basically, I have a metatable with the .__index metamethod in it. It allows me to "read" properties from Trello objects. Such as Board.Name, etc. However, there is an error.
attempt to yield across metamethod/C-call boundary
It happens when I try to HTTP GET from the metamethod, is there a way to work around this limitation?
Edit: Apparently I need to include the code, even though I stated exactly what I was doing, so here it is:
This is a modulescript, which in this case is the Board constructor:
local HTTP = game:GetService("HttpService") local keys = require(script.Parent.Parent.keys) local Board = {} function Board:GetObject(id) local NewBoard = {} local Meta = {} Meta.__index = function(_, index) local Properties = {} Properties["Id"] = function() return id end Properties["Name"] = function() local Ret = HTTP:GetAsync("https://api.trello.com/1/boards/"..id..keys) return (HTTP:JSONDecode(Ret).name) end if Properties[index] then return Properties[index]() else error(index.." is not a valid member of Board.") end end setmetatable(NewBoard,Meta) return NewBoard end return Board
Also, I am aware I should pcall() my HTTP functions, but this is a test code, it is intended for testing only, and won't be the final product.
Object orienting lua's a hard process, so best of luck to you. I got tired when I tried to introduce inheritance.
Anyway, the problem is you're calling something that yields like wait() does in __index, http get is not an instantaneous call.
You can try 'spawn'ing a bit of code inside __index that'll update a value once it's finished loading. It might be better though to move the actual code into a 'refresh' function that does the http get, and have the constructor perform a refresh initially if it makes sense to.