how to insert data in database using graphql from reactjs? [duplicate] - javascript

So i have a method that searches for anime by name, API is graphQL.
Here's the important part of the query
const searchQuery = this.state.searchString;
var query = `query Search{
# the rest of the query omitted for brevity
media(type:ANIME, search: ${searchQuery} ){
# ...
}
`
I'm getting two types of errors in response, first is when search string consists of multiple words separated by spaces - "Syntax Error: Expected :, found )"
Second when i search for single word - "Field "media" argument "search" requires type String, found naruto."
What is the problem here?
You can see full code here - https://github.com/red4211/react-anime-search , app deployed to github pages, search API response goes to console - https://red4211.github.io/react-anime-search/

The issue is that given some query like "naruto", your current code results in the following text:
media(type:ANIME, search: naruto ) {
This is not valid syntax since String literals should be surrounded by double quotes (").
Don't use string interpolation to provide dynamic values to the query. These should always be expressed as variables and included as a separate object inside your request alongside query.
You need to define the variable as part of your operation, providing the appropriate type
var query = `query Search ($searchQuery: String!) {
then you can use the variable anywhere inside the operation:
media(type:ANIME, search: $searchQuery) {
Now just pass the variable value along with your request.
body: JSON.stringify({
query,
variables: {
searchQuery,
}
})
Note that the variable name is prefixed with a $ inside the GraphQL document, but outside of it, we don't do that.

media() looks like a function, so in that case the correct syntax would be:
media(type="ANIME", search=searchQuery)
or if the argument of media() is an object
media({type: "ANIME", search: searchQuery})
Also, you don't need to use ${} around searchQuery since searchQuery is already a string. The usage for that would be something like
`${searchString}` or `foo${searchString}bar`
using the `` around the ${} utility to represent a string and its variable inside the string literal.
Hope it helps!

Related

Process extracted array of values into a formatted string value in JMeter

In JMeter, I have extracted multiple values in a page response to an arraylist using regex extractor (see extracted value below). I need to process the extracted values into an variable in the format (see required output below) and substitute in the following request. How can this be achieved?
Required Output:
44772164,44772175,44772176,44772177
Extracted Value
Match count: 4
Match[1][0]=propertyKey="44772164">
Match[1][1]=44772164
Match[2][0]=propertyKey="44772175">
Match[2][1]=44772175
Match[3][0]=propertyKey="44772176">
Match[3][1]=44772176
Match[4][0]=propertyKey="44772177">
It's not an "arraylist", however our understanding of what "arraylist" is might be different
What you're showing doesn't look like JMeter Variables to me
If you used 'propertyKey' as the "Name of created variable" and your Regular Expression Extractor configuration look like:
You can generate your "Required Output" using a suitable JSR223 Test Element and the code like:
def requiredOutput = new StringBuilder()
1.upto(vars.get('propertyKey_matchNr') as int, {
requiredOutput.append(vars.get('propertyKey_' + it))
if (it as int < vars.get('propertyKey_matchNr') as int) {
requiredOutput.append(',')
}
})
log.info('Required output: ' + requiredOutput as String)
Demo:
Also be aware that using regular expressions for fetching data from HTML documents is not the best idea, you should rather use CSS Selector Extractor for HTML and XPath2 Extractor for XML.

GraphQL optional Query Arguments

I know you can set arguments in a schema to default values but is it possible to make the argument limit argument completely optional in my GraphQL Schema?
Right now it seems like when I hit this without specifying a limit I think that's why I get Int cannot represent non-integer value: undefined
const schema = buildSchema(`
companies(limit: Int): [Company]
...)
I want to be able to skip the limit so that it gets all companies.
In JS, I call it like this:
query: `query {
companies(limit: ${limit}) {
...
but sometimes I don't want to specify a limit. So what is happening is the client is sending crafters(limit: undefined) and it's probably trying to convert that to Int. I'm not sure how to not send limit in and how to make that entire param optional.
(I also read that from the client I should be instead specifying the arguments as variables like query($limit: Int) { companies(limit: $limit) { I guess from my client, from JS? If so how would I send in my limit JS variable into that?
Arguments in GraphQL are nullable (i.e. optional) by default. So if your type definition looks like this:
companies(limit: Int): [Company]
there is nothing else you need to do to make limit optional -- it already is. If you wanted to make limit required, you would make it non-nullable by appending a ! to the type like this:
companies(limit: Int!): [Company]
The errors you are seeing are unrelated to the type of the limit argument. The issue is with the query that you're sending, which based on the error messages, looks something like this:
query ($limit: Int){
companies (limit: undefined) {
# ...
}
}
There's two issues here: One, you are defining a variable ($limit) that you never actually use inside the query (as indicated by the second error). Two, you are setting the limit to undefined, which isn't a valid literal in GraphQL.
Instead of using string interpolation, you should use variables to pass any dynamic values to your query. For example:
query ($limit: Int){
companies (limit: $limit) {
# ...
}
}
If the variable is nullable (notice we used Int instead of Int!), then it can be omitted from the request entirely, effectively making the value of the argument undefined server-side. It's unclear how you're sending your requests to the server, but assuming you're not using some client library, you can check the documentation here for how to structure your request. Otherwise, check your library's documentation for how to correctly use variables with your query.
Below is an example of how you could define a query on client and pass non-required argument. Not sure about your client-side config, but you may want to use a lib like graphql-tag to convert string to AST.
const GET_COMPANIES = gql`
query Companies($limit: Int) {
companies(limit: $limit) {
... // return fields
}
}
`;

Axios get one parameter with multiple values separated by comma

I have a table in React with data about tests which I get from API. I have to do filters on frontend and be able to join them, for example filter tests from chosen category, chosen difficulty and created before some data.
If I wanted to filter for example tests from category "Javascript" and difficulty "Junior", I should get the uri:
/api/admin/filters?filter=category:Javascript,difficulty:JUNIOR
If I wanted to filter tests for "Junior" or "Mid" I should get:
/api/admin/filters?filter=difficulty:JUNIOR,difficulty:'MID
Note apostrophe here which stands for "or".
I should also be able to filter by creation date, for example:
/api/admin/filters?filter=creationDate<2019-09-23 17:34:21,creationDate>2019-09-12 17:34:21
I wonder how I can create such queries? URLSearchParams or axios params adds parameters separated by & so I can't use it here because I have one parameter "filter" with multiple values. Or maybe I should use it and also use js replace method for replacing & for comma? I have also no idea how to add apostrophe.
I saw similar question here: https://spectrum.chat/react/general/query-string-sending-multiple-value-to-the-same-parameter~5d029da0-e7da-443d-a4b2-1529ca7b4f82
but I can't use an array in my case because I have multiple filters. I suppose I have to create object like:
options = {
difficulty: [junior, mid],
category: [javascript],
created before: 2019-09-23 17:34:21,
created after: 2019-09-12 17:34:21
}
and now how to add keys and values from such object to uri so it looks like backend expects?
Any help would be appreciated.
Encoding parameters with encodeURI before passing to axios might solve your issue.
If you need to pass parameters with special characters (like '[',']' ...etc) you should give the parameter as a string '["junior","mid"]' instead of giving parameter as an array.
(Giving as an array will just remove the brackets)
var params = '["junior","mid"]'
encodeURI(params) // it returns "%5B%22junior%22,%22mid%22%5D"
var params = ["junior","mid"]
encodeURI(params) // it returns "junior,mid"

Form a string in typescript with all attendees in Google Calendar API

I am trying to create an event using Google Calendar API using HTTP method.I am writing all my code in typescript.
Now, I have an array containing the email ids of all the attendees that we want to add to that event. So, to pass all those email ids of the attendees in a single query parameter, I am trying to form a single string in the exact format as that shown in API docs. But after forming the string, when I make the API request from server side code, it somehow passes unwanted backslash in that string.
I have tried forming a string by concatenating the keyword email which is to be sent in front of every email that I want to include as attendee. I tried using single backslash () as an escape sequence to insert double-inverted commas, but it didnt work.
I have also tried doing the same thing using join() function, but still unwanted backslashes get introduced in the string when I passed it as attendee parameter value in Create Event API call.
The expected format of string I need to pass in the API call is :
"attendees": [
{
"email": "xyz#gmail.com"
},
{
"email" : "abc#gmail.com"
}
]
The function I am trying to form the string is -
for (let index = 0; index < email_ids.length-1; index++) {
mapping = mapping + "{'email':"+"'"+email_ids[index]+"'}";
if((email_ids.length-1)!=index) {
mapping=mapping+ ",";
}
}
Here mapping is the string I am trying to form.
Now the problem is when I console.log this mapping string, it prints something like -
{'email': " xyz#gmail.com '} , {'email': " abc#gmail.com '}
which is exactly something I want to pass inside the attendee parameter. But when I read the logs of the API request that I sent, I see the parameter attendee to be something like -
"attendees":["{\'email\': \\" xyz#gmail.com \'} , {\'email\': \\" abc#gmail.com \'} "]
There are these unwanted backslashes that get introduced at every point of concatenation in my above function, and I want to remove these. I think this is the reason why I am creating a public event but it isn't adding the attendees to that event, so this adding attendees part is not working as expected.
Any help is appreciated. Thanks a lot in advance.
You seem to be generating a string, and passing this back to whatever method is sending the data. Like Dan D said in a comment, try creating an object instead, as it seems that's what the interface is expecting in the atendees[] field.
This also simplifies your code a lot:
const list = email_ids.map((id: string) => ({ email: id }));
This creates a full list. In on your code you skip the last item in email_ids. I'm assuming it's an error, but if not, you can do it this way:
const list = email_ids
.filter((_:string, i:number)=> i < email_ids.length -1)
.map((id: string) => ({ email: id }));
This will generate an Array with the objects, as in
[
{ email: "xyz#gmail.com" },
{ email: "abc#gmail.com" }
]
Also, notice your code seems to be transforming the data into an array somewhere already:
"attendees":["..."]
So to avoid an array inside of an array, you'll need to figure out what's going on and how to pass/receive the correct data. It's hard to say without looking at the whole lifecycle of that payload from generation to sending to the server.
Lastly: in general, there's no reason to generate JSON by hand. In fact, I can't think of a single reason where anyone would ever want or need to create a JSON source code directly. If you really need a string rather than ab object, creating an object (like above) and calling JSON.stringify() on it later is the right solution.

Query String generated by $.param() include square brackets for array

I have an object like this:
var queryObject= {
name: 'Shwetanka',
subjects: ['Mathematics', 'Physics', 'Computers'],
stream: 'science'
};
When I create query string with this using $.param(queryObject) I get this as query string:
name=Shwetanka&subjects%5B%5D=Mathematics&subjects%5B%5D=Physics&subjects%5B%5D=Computers&stream=science
Expected: name=Shwetanka&subjects=Mathematics&subjects=Physics&subjects=Computers&stream=science
How do avoid [] added by the method in the query string for params with same name. In the backend I'm using struts2 to read params.
I've found the solution. I just have to pass 'traditional=true' in $.param(queryObject, true). This generates the query string i want.
When we have fields with same name in a form and it is submitted via GET/POST, it is bound to be send as an array of params with the same name.
And the server would be expecting the values as such. So, Even if you somehow remove that [], it ceases to be an array, and the server will get only one value.
jQuery param method is designed, with the same thing in mind.
Check out examples in http://api.jquery.com/jQuery.param/.

Categories

Resources