I'm not quite sure what my problem is here.
This is my json:
user = {
userdata: {
name: "Test"
}
}
And while user.userdata.name returns Test,
user["userdata.name"] returns undefined.
Also user["userdata"] is returning the userdata json just as well. And user["userdata"]["name"] is also returning Test.
I'm using the same method on another json, but not searching to deep. just for userdata. and there is works just fine...
And while user.userdata.name returns Test, user["userdata.name"] returns undefined.
Correct. The bit in quotes is used, in its entirety, as the property name to look up. It's not parsed. Since your user object doesn't have a property called userdata.name (it has userdata, which in turn has name), the value you get is undefined.
If you wanted to access that name with brackets notation it would be user["userdata"]["name"] (where the strings can be literal strings, as shown, or the result of any expression such as a variable lookup, string concatenation, etc.).
Can Access like this.
user["userdata"]["name"]
Related
This is my very simple scenario. I'm passing in a JSON to an Input Transformer within EventBridge, and I'd like for the output template to be a transformed JSON where all values are strings. The input paths are fairly standard, nothing special.
In the template however, in order to enforce the above scenario, I define all the mappings as such:
{
"zip" : "<userZip>"
}
That works fine if the input JSON is either 1) a string already, or 2) an integer. However, if I pass in an empty string, I believe the input transformer itself fails, and will not send the result to a target and instead return a FailedInvocation error. I cannot guarantee that the value from the input JSON will always be populated with a value.
How would I go about configuring input transformer to enforce that every mapped value is a string?
I would like to HTTP POST values directly as JSON to an addBook resolver already declared in my GraphQL Mutation.
However, the examples I've seen (and proven) use serialisation of parameters from JSON to SDL or re-declaration of variables in SDL to bind from a Query Variable.
Neither approach makes sense because the addBook mutation already has all parameters and validation declared. Using these approaches would lead to unnecessary query serialisation logic having to be created, debugged and maintained.
I have well-formed (schema- edited and -validated) JSON being constructed in the browser which conforms to the data of a declared GraphQLObjectType.
Can anyone explain how to avoid this unnecessary reserialisation or duplication when posting against a mutation resolver?
I've been experimenting with multiple ways of mapping a JSON data structure against the addBook mutation but can't find an example of simply sending the JSON so that property names are be bound against addBook parameter names without apparently pointless reserialisation or boilerplate.
The source code at https://github.com/cefn/graphql-gist/tree/master/mutation-map is a minimal reproducible example which demonstrates the problem. It has an addBook resolver which already has parameter names, types and nullability defined. I can't find a way to use JSON to simply POST parameters against addBook.
I'm using GraphiQL as a reference implementation to HTTP POST values.
I could write code to serialise JSON to SDL. It would end up looking like this which works through GraphiQL:
mutation {addBook(id:"4", name:"Education Course Guide", genre: "Education"){
id
}}
Alternatively I can write code to explicitly alias each parameter of addBook to a different query which then allows me to post values as a JSON query variable, also proven through GraphiQL:
mutation doAdd($id: String, $name: String!, $genre: String){
addBook(id:$id, name:$name, genre:$genre){
id
}
}
...with the query variable...
{
name: "Jonathan Livingstone Seagull",
id: "6"
}
However, I am sure there's some way to directly post this JSON against addBook, telling it to take parameters from a Query Variable. I'm imagining something like...
mutation {addBook($*){
id
}}
I would like a mutation call against addBook to succeed, taking named values from a JSON Query Variable, but without reserialisation or redeclaration of the properties to parameter names.
This boils down to schema design. Instead of having three arguments on your field
type Mutation {
addBook(id: ID, name: String!, genre: String!): Book
}
you can have a single argument that takes an input object type
type Mutation {
addBook(input: AddBookInput!): Book
}
input AddBookInput {
id: ID
name: String!
genre: String!
}
Then your query only has to provide a single variable:
mutation AddBook($input: AddBookInput!) {
addBook(input: $input) {
id
}
}
and your variables look something like:
{
"input": {
"name": "Jonathan Livingstone Seagull",
"genre": "Fable"
}
}
Variables have to be explicitly defining as part of the operation definition because GraphQL and JSON are not interchangeable. A JSON string value could be a String, an ID or some custom scalar (like DateTime) in GraphQL. The variable definitions tell GraphQL how to correctly serialize and validate the provided JSON values. Because variables can be used multiple times throughout a document, their types likewise cannot simply be inferred from the types of the arguments they are used with.
EDIT:
Variables are only declared once per document. Once declared, they may be referred to any number of times throughout the document. Imagine a query like
mutation MyMutation ($id: ID!) {
flagSomething(somethingId: $id)
addPropertyToSomething(id: $id, property: "WOW")
}
We declare the variable once and tell GraphQL it's an ID scalar and it's non-nullable (i.e. required). We then use the variable twice -- once as the value of somethingId on flagSomething and again as the value of id on addPropertyToSomething. The same variable could also be used as the value to a directive's argument too -- it's not limited to just field arguments. Notice also that nothing says the variable name has to match the field name -- this is typically only done out of convenience.
The other notable thing here is that there's two validation steps happening here.
First, GraphQL will check if the provided variable (i.e. the JSON value) can be serialized into the type specified. Since we declared the variable as non-null (using !), GraphQL will also verify the variable actually exists and is not equal to null.
GraphQL will also verify that the type you specified for the variable matches the types of the arguments where it's actually used. So an Int variable will throw if it's passed to a String argument and so on. Moreover, nullability is checked here too. So an argument that is an Int! (non-null integer) will only accept variables that are also Int!. However, an argument that is Int (i.e. nullable) will accept either Int or Int! variables.
The syntax that exists is there for a reason. The kind of syntax you're imagining would only make sense in a specific scenario where you're only querying a single root field and using all the variables as arguments to that one field and the variable names match the argument names and you don't need to dynamically set any directive arguments.
I would like something similar to what node-odata offers, but I do not want to wrap it around my database (I am using Cassandra and already have an Express app set up with routes, etc).
Currently, I grab data from the database (which will ultimately return a JSON object to the user) and then using the values passed in the query string I modify the results with JavaScript and pass the modified JSON object on through to the user.
I cannot pass in a query string like this http://localhost:3001/getSomeData?name=jim&age=21||eyeColor=red which includes logical operators in the query string, and would grab all data and filter it where the name is "jim", the age is "21" OR eyeColor is "red". So this would give me all Jims that have either eyeColor red and/or age of 21. If I used this age=21&&eyeColor=red I would expect to get all Jims that have BOTH eye color of red and are 21 years old.
I was thinking of using a custom query string that can be passed in (i.e. inclusive=age&inclusive=eyeColor appended at the end of the query string) and in Node, I would modify the filter results to treat these properties (age and eyeColor) as if they were passed in with the || OR operator). However, this is quite verbose, and I was hoping there was a library or another simpler implementation out there that solves this problem, or somehow lets me pass in simple logical operators into the query string.
I ended up using this library to achieve what I wanted: https://www.npmjs.com/package/jspath
It's well document and worked perfectly for my situation.
npm i querystringify //or
https://cdnjs.cloudflare.com/ajax/libs/qs/6.7.0/qs.min.js
//it will will return an object
const myObject = Qs.parse(location.search, {ignoreQueryPrefix: true});
//you can use object destructuring.
const {age,eyeColor}=Qs.parse(location.search, {ignoreQueryPrefix: true})
By default, parsing will include "?" too.
{ignoreQueryPrefix: true} this option will omit "?".
I'm new to Go. I was trying to fetch and marshal json data to a struct. My sample data looks like this:
var reducedFieldData = []byte(`[
{"model":"Traverse","vin":"1gnkrhkd6ej111234"}
,{"model":"TL","vin":"19uua66265a041234"}
]`)
If I define the struct for receiving the data like this:
type Vehicle struct {
Model string
Vin string
}
The call to Unmarshal works as expected. However, if I use lower case for the fields ("model" and "vin") which actually matches cases for the field names in the data it will return empty strings for the values.
Is this expected behavior? Can the convention be turned off?
Fields need to be exported (declared with an uppercase first letter) or the reflection library cannot edit them. Since the JSON (un)marshaller uses reflection, it cannot read or write unexported fields.
So yes, it is expected, and no, you cannot change it. Sorry.
You can add tags to a field to change the name the marshaller uses:
Model string `json:"model"`
See the documentation for more info on the field tags "encoding/json" supports.
I would like to ask on this:
I have object with data for request and i would like to hash value options.data.password:
Here is how i do it:
var hashedPassword = CryptoJS.SHA1(options.data.password);
alert(hashedPassword); // This is correctly value
options.data.password = hashedPassword;
Problem is that if i looked into updated JSON object i saw something like this:
But i was expected just hashed string value, not object.
NOTE: If I update value manually (without hashing function) is everything displayed correctly.
How can i solve it?
Thanks for any help.
Per the CryptoJS documentation:
The hash you get back isn't a string yet. It's a WordArray object. When you use a WordArray object in a string context, it's automatically converted to a hex string.
Your property assignment and subsequent JSON.stringify do not know you want to use it as a string.
You need explicitly make it a string by calling its .toString(). Again, from the docs:
You can convert a WordArray object to other formats by explicitly calling the toString method and passing an encoder.
options.data.password = hashedPassword.toString(CryptoJS.enc.Base64);
FYI, The receiving end of this hash needs to know what encoding method was used (Base64 in this example) in order to accurately work with it.
From the documentation of CryptoJS:
The hash you get back isn't a string yet. It's a WordArray object. When you use a WordArray object in a string context, it's automatically converted to a hex string.
The JavaScript object returned has a toString() method which is why when you use it as a string (in alert) it gets converted to one.