sending value of my textarea with graphql - javascript

I hope you all have a great day. I am coding my own personal website and I have a section called to contact me. The problem I have with this section is that I am trying to send my client email to my email and when I am trying to send their message to my server through Graphql I get this error
[
{
"message": "Syntax Error: Unterminated string.",
"locations": [
{
"line": 3,
"column": 123
}
]
}
]
the request I sent to my server is
'\n mutation{\n sendEmail(EmailInput: {name: "Test name", email: "Test#email.com",
subject: "this is test subject", message: "\n
this is the first line \nthis is the second line\nwhen I have multiple lines I have these problem\n
"}) {\n success\n message\n }\n }\n '
I don't know how to fix it I don't know why I get this error.
I used fetch to send my code backend :
const emailMutationQuery = `
mutation{
sendEmail(EmailInput: {name: "${senderName.value}", email: "${senderEmail.value}", subject: "${senderSubject.value}", message: "
${senderMessage.value}
"}) {
success
message
}
}
`;
const result = await fetch("http://localhost:2882/graphql", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
query: emailMutationQuery,
}),
});
const convertedResult = await result.json();

GraphQL supports variables, which can be used to supply input data separately from the query. The variables are just a separate JSON-encoded object. This avoids syntactic difficulties (and potential security risks!) from trying to embed the inputs directly in the query.
For this you'd write a fixed query, that declares and uses the variable, but doesn't depend on the per-request inputs
const emailMutationQuery = `
mutation SendEmail($emailInput: SendEmailInput!) {
sendEmail(EmailInput: $emailInput) {
success
message
}
}
`;
You'd then create a second object containing the variable(s). The top-level keys match what you declare in the GraphQL operation line, and their content matches the corresponding GraphQL input types.
const variables = {
emailInput: {
name: senderName.value,
email: senderEmail.value,
subject: senderSubject.value,
message: senderMessage.value
}
};
Note that this is an ordinary Javascript object, and we haven't quoted or escaped anything here.
Now when we make the request, we send the query and variables together
const result = await fetch("http://localhost:2882/graphql", {
...,
body: JSON.stringify({
query: emailMutationQuery,
variables: variables
})
});
Things like newlines in the message content will be escaped in the variables block, and get passed through correctly to the underlying GraphQL engine.

I actually find a solution for it but feel free to share your answers here. The solution I found for this problem was that you have to use JSON.stringify() for the textarea. you have to pass your textarea value to this function and js will take care of the rest. my code now looks like this
const emailMutationQuery = `
mutation{
sendEmail(EmailInput: {name: "${senderName.value}", email: "${senderEmail.value}", subject: "${senderSubject.value}",
message:${JSON.stringify(senderMessage.value)}}) {
success
message
}
}
`;
I hope this help you guys.

Related

sendgrid mail sending error upon placing multiple receiver

I'm using const sgMail = require('#sendgrid/mail'); and utilizing sendgrid version 7.6.2.
When I'm adding two email addresses in array and passing that into send() or sendMultiple() it's throwing me error like this.
status: 'failed',
> Error: Error: String expected for `email`
here's the section where I'm putting the multiple emails,
mailsTo = {
email: ["demo#email.com", "demo1#email.com"],
name: "demo",
type: 'to'
}
here if I pass one email as in form of string the mail is getting triggered. Can anyone please suggest what am I doing wrong.
Thanks in advance
According to the documentation the addresses are to be passed as an array of EmailData (string or object with email and name).
Please try the following:
mailsTo = [
{
email: "demo#email.com",
name: "demo"
},
{
email: "demo1#email.com",
name: "demo"
}
]
Assuming mailsTo is being pass as the to parameter for

Why is my JSON invalid when making post request? (Postgres, Knex)

I've been playing around with this for a while, and I have to say I'm rather stumped.
I have a table called "physical_sites", and created the column "history" as a "json" type in this table.
My API request function is as follows:
const response = await fetch(BASE_URL + "physical_sites", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ data: jobSite }),
});
With my incoming data as:
{
"physical_site_name": "Here",
"physical_site_loc": "test",
"created_by": "ME",
"status": "Active",
"history": [{
"action_date": "2022-07-21T01:22:44.056Z",
"action_taken": "Create Job Site",
"action_by": "me",
"action_by_id": 24,
"action_comment": "Initial Upload",
"action_key": "1jt9JPRLy7RHJUwmz3kqoy98u"
}]
}
I will continually be adding items to the 'array' in history, so there will be multiple objects here. I checked this in an online JSON validator, and it seems correct.
Lastly, my "create" function in the controller is as follows:
async function create(req, res) {
const result = req.body.data;
console.log(result);
const data = await knex("physical_sites")
.insert(result)
.returning("*")
.then((results) => results[0]); //insert body data into assets
res.status(201).json({ data });
}
Fairly simple.
However, I keep getting this error:
message: 'insert into "physical_sites" ("created_by", "history", "physical_site_loc", "physical_site_name", "status") values ($1, $2, $3, $4, $5) returning
* - invalid input syntax for type json'
Not exactly sure what is going on, can someone help me understand what I'm missing?
Thanks.
Most likely one of you column for this table has a JSON type. I believe that it is the history column.
You could parse the history property to String before sending the request.
// ...
body: JSON.stringify({
data: {
...jobSite,
history: JSON.parse(jobSite.history)
}
}),
// ...

Dynamic sendgrid templates being sent as plain text

I'm sending email through sendgrid, but when I receive the email, the email is in plain text format, and I would like to send it in html format.
The variable data is the data I pass to sgMail.send.
module.exports = {
data: {
to: '',
from: '',
subject: '',
text: '',
templateId: '',
dynamic_template_data: {
value_precip: undefined,
value_humidity: undefined,
value_windSpeed: undefined,
value_condition: undefined,
value_activiti: undefined
}
},
set: function(to, from, subject, text, templateId, params) {
this.data.to = to
this.data.from = from
this.data.subject = subject
this.data.text = text
this.data.templateId = templateId,
this.data.dynamic_template_data.value_precipitation = params.value_precipitation
this.data.dynamic_template_data.value_humidity = params.value_humidity
this.data.dynamic_template_data.value_windSpeed = params.value_windy
this.data.dynamic_template_data.value_condition = params.value_condition
this.data.dynamic_template_data.value_activiti = params.value_activiti
},
send: function() {
try {
sgMail.send(this.data)
} catch (error) {
console.log(error)
}
}
}
I don't know what may be causing this problem, if anyone can help me I would be grateful!
It's simple, just remove the text.
As mentioned by a contributor of SendGrid. Read more
Given that dynamic templates contain both HTML and plain text content, text should not be passed when using a dynamic template.
It looks like SendGrid uses html attribute to decide if the content type should be html even though they ignore the content. So, just include that attribute in the payload. Seems weird, but it worked for me.
P.S.: I didn't try it with JavaScript, I'm using Python.

Apollo Server, Graphql - Must provide query string

Im not sure what im doing wrong here? I've been stuck now for soem time on getting my mutations to run with my apollo-server-lambda in my serverless setup, my queries works fine bu when i try to run a query like this:
{ "mutation": "{ signIn(username: \"SomeUser\", password: \"SomePassword\" ) { token } }" }
I just get the message: " Must provide query string." status 400.
I've set up my resolver like so:
const resolvers = {
Query: {
users: async (_, args, ctx) => User.load(args, ctx)
},
Mutation: {
signIn: async (_, { username, password }, ctx) => Auth.signIn({ username, password }, ctx)
}
};
For additional infor here is my typeDefs:
const typeDefs = gql`
type User {
id: ID!,
firstname: String,
lastname: String,
username: String,
createdAt: String,
role: String
}
type AuthToken {
token: String
}
type Query {
hello: String,
users(id: Int): [User]
}
type Mutation {
signIn(username: String!, password: String!): AuthToken!
}
`;
I'm using postman to test my graphql endpoint and my content type is application/json
I dont know if any one here can tell me what im doing wrong, i tryed to move it all to Query resolver, and it works replace "mutation" with "query" then but it dosent make sens to me using the "query" here and i guess later on when i actually want to use the Mutation to mutate data i would need this to work anyway?
Can any one tell me where im wrong here?
EDIT
I installed: graphql-playground-middleware-lambda and set up the serverless setup with: https://github.com/prisma/graphql-playground#as-serverless-handler and if i use Graphiql it works as intented, but im still interested if any one knows whats wrong with the json i send via postman?
When sending the request, your request body should be a properly-formatted JSON object, with a query property (and optionally, a variables property if including variables):
{
"query": "<GraphQL Document>",
"variables {},
}
This is the case whether the operation itself is a query or a mutation.
The actual value of the query property above must be a syntactically correct document, as outlined in the GraphQL specification. A document will typically consist of a single operation definition (either a query or a mutation) that includes all the requested fields for that operation. The document will also include fragments, if using any.
An operation definition looks like this:
OperationType [Name] [VariableDefinitions] [Directives] SelectionSet
So you could have a document like this:
mutation SomeMutation {
signIn(username: "SomeUser", password: "SomePassword") {
token
}
}
Here, the type of the operation is mutation, the name is SomeMutation and everything between the outermost set of curly brackets is the selection set. If you had any variables, their types would be declared in parentheses before the selection set.
The operation name is optional, but it's helpful to include it for debugging purposes on the backend. Technically, the operation type can be omitted as well, in which case GraphQL simply assumes the type is a query. For example, this is still a valid document:
{
users {
id
}
}
and is equivalent to
query SomeName {
users {
id
}
}
The former is referred to as query shorthand. Obviously, this cannot be used for mutations, so mutations must always explicitly state their operation type. A complete example:
{
"query": "mutation SomeName ($username: String!, $password: String!) { signIn(username: $username, password: $password) { token } }",
"variables {
"username": "SomeUser",
"password": "SomePassword"
},
}

SendGrid Content Templating with Nodejs

How do I template SendGrid's content with Nodejs?
I am trying to send emails from contact form in an application using SendGrid. I have a Google Cloud Function that I am calling via an HTTP post. I am able to pass in the form data as a JSON object to my Google Cloud Function, and display a raw JSON object in my email content, but when I try to template my SendGrid content, the JSON object's properties keep coming back as undefined. How do I display my different formData properties within my SendGrid email content?
Here is the code:
const functions = require('firebase-functions');
const sg = require('sendgrid')(
process.env.SENDGRID_API_KEY || '<my-api-key-placed-here>'
);
exports.contactMail = functions.https.onRequest((req, res) => {
contactMail(req.body);
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.send("Mail Successfully Sent!");
})
function contactMail(formData) {
const mailRequest = sg.emptyRequest({
method: 'POST',
path: '/v3/mail/send',
body: {
personalizations: [{
to: [{ email: 'my.email#gmail.com' }],
subject: 'Contact Us Form Submitted'
}],
from: { email: 'noreply#email-app.firebaseapp.com' },
content: [{
type: 'text/plain',
value: `
You have received a contact us form submission. Here is the data:
Name: ${formData.userFirstName} ${formData.userLastName}
Email: ${formData.userEmail}
Subject: ${formData.formSubject}
Message: ${formData.formMessage}
`
}]
}
});
sg.API(mailRequest, function (error, response) {
if (error) {
console.log('Mail not sent; see error message below.');
} else {
console.log('Mail sent successfully!');
}
console.log(response);
});
}
This displays undefined for each template expression.
However if my content section is set to this:
content: [{
type: 'text/plain',
value: formData
}]
Then the email content is displayed as a raw JSON object.
How do I clean up my SendGrid email content and display my JSON data in a formatted, cleaner way?
The problem was my req.body was a text string, not a JSON object.
Using const formData = JSON.parse(req.body); and then passing this variable to contactMail will properly display the JSON object's properties in an ES6 template literal.

Categories