JSON deserialisation object disposal - jade-platform

I have some code like this:
vars
json: JadeJson;
objs: ObjectArray;
foo: Foo;
begin
create json transient;
create objs transient;
foo := json.parse(response, Foo, objs).Foo;
// Do something with foo
epilog
delete json;
delete objs;
end;
Is foo deleted by the call to delete objs, or do I need to dispose of it (any any other object stored in objs) separately?

The documentation doesn't specify for the return value, but for the createdObjects parameter it says "It is the responsibility of the caller to delete all objects returned from the method." so I would think it doesn't get deleted automatically.
You could test this by storing a reference to foo somewhere and after the method returns check to see if it's a valid object reference.

Related

FastAPI: Return response with an array of objects

I'm currently working on a API that returns scraped data. The data is stored as an array but when I go return that array as a response on an endpoint, I get the following error:
pydantic.error_wrappers.ValidationError: 1 validation error for InnerObject
response
value is not a valid dict (type=type_error.dict)
Here's a simplified version of what I'm trying to achieve:
class InnerObject(BaseModel):
foo: str
class OuterObject(BaseModel):
bar: List[InnerObject]
#app.get("/test_single", response_model=InnerObject)
def test():
return InnerObject(foo="Hello Mars")
#app.get("/test_multiple", response_model=OuterObject)
def test():
objects = [InnerObject]
objects.append(InnerObject(foo="Hello Earth"))
objects.append(InnerObject(foo="Hello Mars"))
return objects
I have an array of objects that I want to return as a response. It's also possible that I don't need outer/inner models but I have also attempted this and set the response_model to be response_model=List[InnerObject]. Returning a single InnerObject as seen in the "/test_single" endpoint works fine, so I assume it's to do with trying to return a [InnerObject]
Thanks for any responses in advance
Solution
Thanks kosciej16, the problem was that I was adding the object name when declaring the list. So I was going objects = [InnerObject] when I should have been going objects = []
Generally fastapi tries to create OuterObject from thing you return.
In such case you have few options.
Create object explicitly
#app.get("/test_multiple", response_model=OuterObject)
def test():
objects = []
objects.append(InnerObject(foo="Hello Earth"))
objects.append(InnerObject(foo="Hello Mars"))
return OuterObject(bar=objects)
Change response_model
#app.get("/test_multiple", response_model=List[InnerObject])
def test():
objects = []
objects.append(InnerObject(foo="Hello Earth"))
objects.append(InnerObject(foo="Hello Mars"))
return objects
Change definition of OuterObject
class OuterObject(List[InnerObject]):
pass

Async method that consumes self causes error "returns a value referencing data owned by the current function"

Is it possible to consume self in an async method?
Here is my method (please note the poller is unrelated to the poll method in rust futures).
pub async fn all(self) -> WebDriverResult<Vec<WebElement<'a>>> {
let elements = self.poller.run(&self.selectors).await?;
Ok(elements)
}
and for completeness, here is the struct it belongs to:
pub struct ElementQuery<'a> {
session: &'a WebDriverSession,
poller: ElementPoller,
selectors: Vec<ElementSelector<'a>>,
}
NOTE: session is passed in via the new() fn. It is owned by the caller that creates ElementQuery and runs it to completion. The above method should return Vec<WebElement>.
The error says:
error[E0515]: cannot return value referencing local data `self.poller`
--> src/query.rs:193:9
|
193 | self.poller.run(&self.selectors).await
| -----------^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| returns a value referencing data owned by the current function
| `self.poller` is borrowed here
However, as far as I can tell, I am not returning any references owned by the current function. The only reference being returned (inside WebElement) is session, which I passed into the struct to begin with.
I can change the ? to unwrap() so that the only return path is Ok(elements) just to eliminate any other possibilities (same error).
Here is WebElement:
#[derive(Debug, Clone)]
pub struct WebElement<'a> {
pub element_id: ElementId,
pub session: &'a WebDriverSession,
}
ElementId is just a newtype wrapper around String - no references.
Is this something to do with the method returning a Future that may execute later? and perhaps something to do with something being held over an .await boundary?
If the ONLY reference being returned is &WebDriverSession, and that same reference was passed in via new(), then why is it telling me that I'm returning a reference owned by the function?
EDIT: Managed to get this to compile by effectively inlining some code rather than calling additional async functions. Still not sure why this fails, other than it seems to be related to holding a reference across .await boundaries, even if that reference is not owned by the function/struct on either side.
Here's a playground link with a simplified example:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f38546480aaeb3594c8c17fec9b7d62c

Technique to get an id back with an http query when empty array is returned

Let me first say I have a solution to this problem, but I'm interested in knowing whether there is a better way, and whether I'm doing something wrong.
I have a table of objects on the front-end of a webapp, I need to asynchronously load some data for the objects as it is needed on a per-object basis. The server returns a JSON array containing the data for that object, and the data contains the object's key, so I can update the object on the front-end with its data. When there is no data, I just get an empty array, which unfortunately presents no way of updating the object, since I don't have the key to update it with. This can result in another query later, which is a waste of time/resources. I can't modify the server, is there a way to do this nicely?
My current solution is to just set the object's data to an empty array before sending the request, then just update when the result is received if the result is nonempty.
I was wondering if there is a better/more idiomatic way to do this.
For reference, I'm using Elm with PostgREST as the backend.
You can use currying and partial function application to indicate which object ID should be updated.
I'm assuming you have some code similar to this:
type Msg
= ...
| FetchData Int
| DataFetched [Data]
| DataFetchFail Http.Error
-- inside the update function
update msg model =
case msg of
...
FetchData id =
model ! [ Task.perform DataFetchFail DataFetched (Http.post ...) ]
If you define your DataFetched constructor to include the ID as the first parameter, you can use partial application to include the ID for future lookup, regardless of what the server returns.
Here's the same code chunks with this idea:
type Msg
= ...
| FetchData Int
| DataFetched Int [Data]
| DataFetchFail Http.Error
-- inside the update function
update msg model =
case msg of
...
FetchData id =
model ! [ Task.perform DataFetchFail (DataFetched id) (Http.post ...) ]
You could also add the ID to the Fail message for more fine-grained error messages.

How get autoID of new object after calling push() in firebase?

It's simple. I have an object called obj and the reference called ref
when I do:
ref.push(obj, function(err){});
or
ref.push().set(obj, function(err){});
how do I get the auto generated ID of the recently saved object?
The push function returns a reference to the newly created object.
var newRef = ref.push();
console.log(newRef.name());
newRef.set(obj, function(err) {});
Note that in the above snippet no data is sent to the server until the call to set. The push() method is pure client-side, as long as you don't pass any data into it.
https://www.firebase.com/docs/web/api/firebase/push.html

what is #params in Iron:router

with meteor's IronRouter, I'm trying to use the this.params object elsewhere, but confused as to what it is. It seems to be a zero length array, that is actually an object with named methods after the path components.
# coffee
#route 'magnets',
path: '/magnets/lesson/:lessonCname'
data: ->
if #ready()
debugger;
console.log("route.params", #params)
with this code, in the debug console I will get:
this.params
[]
this.params.lessonCname
"despite-magnets-01"
typeof(this.params)
"object"
this.params.length
0
this.ready()
but in passing the params object to a server method, the methods (ie "lessonCname") disappear.
If my understanding is correct, then the near-term question is what is the best way to retrieve/convert these methods to {property:value} so they can be serialized and passed to server calls?
There are two easy ways of solving your problem, you can either set a global variable from within the data scope (but this is considered bad practice, at least IMO) or you can use the "data" function, which returns the data context for the current template:
data: ->
window._globalscopedata = #params.whatever #setting global variable
return someCollection.findOne #returns data context
_id: #params.whatever
when proccessing this route I will have the whatever param available in _globalscoredata and my document available in the template context.
Take a look at the source code for retrieving the parameters from a path. params is an array, but may have named properties. To iterate over everything, you can use the for in loop:
for(var x in myArray){
// Do something.
}
In this way, you can copy over everything to a new object (there may be a simpler way to create a copy).
The params property attached to a RouteController is an object with the following properties :
hash : the value of the URL hash.
query : an object consisting of key/value pairs representing the query string.
a list of URL fragments with their name and actual value.
Let's take an example, for this route definition :
// using iron:router#1.0.0-pre2 new route definition
Router.route("/posts/:slug");
And this URL typed in the browser address bar : /posts/first-post#comments?lang=en
We can use the console to find out precisely what params will actually contain :
> Router.current().params
Which will display this result :
Object {
hash: "comments",
slug: "first-post",
query: {
lang: "en"
}
}
Here slug is already a property of the params object whose value is "first-post", this is not a method.
If you want to extract from params these URL fragments as an object of key/value pairs, you can use underscore omit :
// getting rid of the hash and the query string
var parameters=_.omit(this.params,["hash","query"]);

Resources