Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failure with transferring 'obj'? #121

Closed
Dzoukr opened this Issue Apr 12, 2019 · 5 comments

Comments

Projects
None yet
2 participants
@Dzoukr
Copy link

Dzoukr commented Apr 12, 2019

Hello @Zaid-Ajaj,

it's been a while. Today I found strange issue and not sure if it's bug or I do it wrong.

I have an API definition:

type API = {
    Test : unit -> Async<obj>
}

with default implemenation:

let api : API = {
    Test = fun _ -> async { return (box "TEST STRING")}
}

Transfer is ok

image

But on Fable side i got to error part of Cmd.ofAsync function:

image

Got any idea what I am doing wrong? This code is just to reproduce of course. In real world I transfer record with obj on it.

Thanks for any help 🙏

@Zaid-Ajaj

This comment has been minimized.

Copy link
Owner

Zaid-Ajaj commented Apr 12, 2019

Hello Roman!

At first glance, this error is expected to happen: the client cannot infer type information from the data at runtime (i.e. the type of the the boxed inner value), only metadata that is types available at compile-time.

Basically when you say: "Here is an obj" the client goes ¯\_(ツ)_/¯ "What do I do with it?".

So can you help me out a bit here:

  • Why are you boxing values??
  • What values are you boxing to be exact?
  • What do you expect the client to do when it is given an obj?
  • How do you intend to use the boxed obj from the client?
@Dzoukr

This comment has been minimized.

Copy link
Author

Dzoukr commented Apr 13, 2019

Hello!

I am trying to work Azure Search API, which is very vague about what kind of values are returned in thing called Facet.

I have basically shared type:

type RangeFacet =
    | From of obj
    | To of obj
    | FromTo of obj * obj

The obj here can be string, decimal, int32 or int64 . Actually, I don't care about value on frontend, I just need to display it (.ToString())

To achieve it, I currently created my own FacetValue union with describing all the possible values, so no problem if you close this issue. I just thought it is possible to somehow pass untyped value from backend. I am not javascript guy at all so I expected to be there something like obj in javascript. :)

@Zaid-Ajaj

This comment has been minimized.

Copy link
Owner

Zaid-Ajaj commented Apr 13, 2019

To achieve it, I currently created my own FacetValue union with describing all the possible values,

This is the right way to do it! Though you can simplify the the type you send to your frontend to something that only includes the formatted string if you only need the .ToString() representation

I just thought it is possible to somehow pass untyped value from backend. I am not javascript guy at all so I expected to be there something like obj in javascript. :)

It is technically possible to send obj of primitive values to the client and with some clever tricks, be able to work them there too

I can work it out by including the FullName of the boxed type into the serialized data from the backend and then inspect this FullName from the frontend as well to determine what to do during deserialization

but this "feature" has many downsides:

  • You still have to type-test the values to work with them from the Fable frontend and runtime type-testing in Fable is a bit flaky (unless you exactly know what type it is, in which case you just unbox but if you know the type, just use it instead of obj)
  • It would only work for primitive types (boxed records, unions, options, list etc. will not be supported): adding FullName to the serialized data is not enough information for generic deserialization
  • It would make your protocol definition hard to understand because obj can be anything

In conclusion, adding support for obj doesn't seem like a good idea. I will add this to the docs sometime soon, maybe a section "Supported Types" would be appropriate.

@Zaid-Ajaj Zaid-Ajaj closed this Apr 13, 2019

@Dzoukr

This comment has been minimized.

Copy link
Author

Dzoukr commented Apr 13, 2019

Thanks @Zaid-Ajaj for great explanation and fully agree - because of one uncommon use case you should not put stability of such great library in risk.

Anyway, that's why I like talking with you - one can always learn something new. Thanks again!

@Zaid-Ajaj

This comment has been minimized.

Copy link
Owner

Zaid-Ajaj commented Apr 13, 2019

Thanks Roman for the kind words, really appreciate it ❤️

Keeping the features at a bare-minimum has indeed resulted in a stable library yet these bugs still creep out every now and then so thanks a lot for taking the time to report these issues!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.