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

type: 'any' in a remote method can coerce mongodb object ids into floats #299

Closed
vkarpov15 opened this issue May 12, 2016 · 11 comments
Closed

Comments

@vkarpov15
Copy link

If you have a remote method with a parameter that's type: 'any', coerce can convert a mongodb object id into a float because mongodb object id hex strings can happen to be all numbers. Easily fixed on my end (use type: 'string') but this is an annoying rough edge in the API IMO.

@richardpringle
Copy link
Contributor

Hey @vkarpov15, those types are LoopBack Types; 'any' is not a type according to the documentation... And now I see that we test for type: 'any' <- @crandmck, think we could add that to the above link?

@vkarpov15, there are several issue with coercion that are currently being "cleaned up" by @bajtos , I will make sure that we consider this as well!

Cheers

@richardpringle
Copy link
Contributor

@bajtos, I keep adding the "coercion clean up" to related bugs. If you have a different workflow in mind please let me know. I'm not sure if your fixes will cover all cases, but at the very least I think we should add documentation for any remaining coercion behavior as a part of the milestone.

@crandmck
Copy link
Contributor

Yes, I can add that.

Is the "Any" type name capitalized, as most of the other LoopBack types are?

Will it match just any primitive type, or will it also match Object, Array, and GeoPoint types?

@vkarpov15
Copy link
Author

It was lower case 'any' unfortunately - I assume the person that wrote it in the first place was anxious about whether the parameter would be a string or a full fledged mongodb ObjectId.

@bajtos
Copy link
Member

bajtos commented May 13, 2016

It's any and it basically means "anything" - a string, a number (used for IDs in SQL databases), or an object like ObjectID, or even an array or a boolean.

I am pondering an idea of always encoding the id property as strings, see strongloop/loopback#2046

@crandmck
Copy link
Contributor

OK, I added it to the table in https://docs.strongloop.com/display/LB/LoopBack+types (and reordered the table alphabetically).

One final question: Will any match a null value?

@vkarpov15
Copy link
Author

IMO if you say "any" that should mean "no type coercion please, let me deal with it"

@bajtos
Copy link
Member

bajtos commented Sep 13, 2016

This issue was fixed by #343 in LoopBack 3.0 (alpha). Model properties of "any" type sent in JSON request body are no longer converted from string to number. When the "any"-typed value comes from a string-only source like query-string, we convert to numbers only values that are "safe" to convert, meaning they we won't loose information as a result of the conversion. Most notably, integer values starting with 0 and values larger than MAX_SAFE_INTEGERS are preserved as strings.

@bajtos bajtos closed this as completed Sep 13, 2016
@vkarpov15
Copy link
Author

Don't rush to release on our account, we've been loopback-free for a few months now and it's been a dream come true :)

@bajtos
Copy link
Member

bajtos commented Sep 14, 2016

Don't rush to release on our account, we've been loopback-free for a few months now and it's been a dream come true

That's sad news. If I may ask you, what tool/framework/approach are you using now?

@Tallyb
Copy link

Tallyb commented Jan 19, 2017

If anyone faces the same issue - here is a boot script that fixes the problem for all methods:

module.exports = function(app) {
    app.models().forEach(model => {
        if (model.settings.permissions) {
            //fixes the id type for all methods
            model.sharedClass._methods.forEach(method => {
                let idArg = method.accepts.find(elem => {
                    return elem.arg === 'id';
                });
                if (idArg && idArg.type === 'any') {
                    idArg.type = 'string';
                }
            });
            // Fixes the id type for the shared constructor
            // This runs on all models but will happen only once for each base model
            // As all models have the same base model shared constructor
            let classCtorIdArg = model.sharedClass.sharedCtor.accepts.find(elem => {
                return elem.arg === 'id';
            });
            if (classCtorIdArg && classCtorIdArg.type === 'any') {
                classCtorIdArg.type = 'string';
            }
        }
    });
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants