-
Notifications
You must be signed in to change notification settings - Fork 2k
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
fix for Objects creation #504
Conversation
Thanks for this - though I have a few notes. First: many of these should not be changed. Second: |
Thanks @leebyron, that's always cool to learn new things :) happy to see this comment! |
After clarifying with lee, the old behavior is the correct one. |
hey @leebyron can you please confirm that it is expected behaviour that object created by graphql is not instanceof Object? (some libs like mine can use |
@pleerock I think it's already answer by @leebyron in this comment: #484 (comment)
query {
toString: me { name }
valueOf: someOtherRealField
}
|
@IvanGoncharov thanks for the deeper explanation |
Mozilla discourages use of null prototypes because of multiple unexpected problems it causes: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create This solution seems worse than the problem it intends to solve (which has multiple other idiomatic solutions - one can either use Map or differentiate between own and inherited properties using available JS functions). It causes (and will continue to cause) multiple issues in the libraries that reasonably expect objects to be ... instances of Object and not instances of null. |
Couldn‘t agree more. I don’t want to know how many developers before have spent hours to finally find this issue / PR as well. I‘m sorry but defining an obviously problematic behavior as „it’s by design“ seems pretty ... uhm, I don’t want to be disrespectful, but ... ignorant. 😔 |
Due to `instanceof` comparison, object without prototype is mistaken for a privative value, throwing `TypeError: Cannot convert object to primitive value.` when trying to `.toString` said object (inside template string). This mostly effects usage with `graphql` as `graphql-js`, [by design](graphql/graphql-js#504), creates objects by using Object.create(null). This fix allows saving these objects. The fix uses `typeof` instead of `toString` comparison since I see no reason why `new Number/Boolean/Date` should be a supported use case. Closes: #2065
Due to `instanceof` comparison, object without prototype is mistaken for a privative value, throwing `TypeError: Cannot convert object to primitive value.` when trying to `.toString` said object (inside template string). This mostly effects usage with `graphql` as `graphql-js`, [by design](graphql/graphql-js#504), creates objects by using Object.create(null). This fix allows saving these objects. The fix uses `typeof` instead of `toString` comparison since I see no reason why `new Number/Boolean/Date` should be a supported use case. Closes: typeorm#2065
I just got bitten by this problem too: this causes bizarre comparison failures in tests that are tricky, non-obvious, and often buried deep inside library code that's difficult to inspect and debug. An option to use ES6 Maps rather than plain objects, as in #2664, might go a long way towards fixing this? |
I also just got bitten by this problem. Not using prototypes on only some types of GraphQL expressions introduces a whole extra dimension of code coverage issues for projects using this project such as Apollo. We cannot necessarily control how a user would issue a query, so we would be at the mercy of the caller as to whether input became a full-fledged |
As @robross0606 suggests, it's strange that valueFromAST and coerceInputValue make different choices as to whether an input object should have a null prototype or not. (I personally have no opinion about which approach is better, but the inconsistency is surprising.) |
graphql should return plain data that can be used safely with other programs. For example, nodejs' native assert will fail when comparing graphql's import assert from 'node:assert/strict';
import gqlreq from './gqlreq.js';
const gqlres = await gqlreq();
console.log(gqlres);
// [Object: null prototype] {
// user: [Object: null prototype] {
// id: 'ywj--Y3SxiXk4TEa04Wz5'
// }
// }
assert.deepEqual(gqlres, {
user: {
id: 'ywj--Y3SxiXk4TEa04Wz5'
}
}); // ERR_ASSERTION, Expected values to be strictly deep-equal |
It was fun reading the comments but did we actually found a way to fix this or do we still think it's actually a feature not an issue ? 😂 |
returned Objects did not have proper protoype.
Closes #484