import dbConnect from '../../../utils/mongo'
import Product from '../../../models/Product'
export default async function handler(req, res) {
const {method} =req;
dbConnect();
if(method ==="GET"){
try{
const products = await Product.find();
res.status(200).json(products);
}
catch(err){
res.status(500).json(err);
}
}
if(method ==="POST"){
try{
const product = await Product.create(req.body);
res.status(201).json(product);
}
catch(err){
res.status(500).json(err);
}
}
}
So here I want to use res.status(200).json(products); to perform the get operation,
however, I'm receiving the error:
API resolved without sending a response for /api/products, this may result in stalled requests
When trying to run the get request with postman or axios, however post request works just fine. Any suggestions to solve it would be welcome
For anyone still looking for a solution for this, export this from the api route, you can just add the following code to your endpoint and it should resolve that :
export const config = {
api: {
externalResolver: true,
},
}
note that this will disable the warning!
Good evening everyone. Today I tried writing a code to add a user to mongodb database which requires the following fields - name, email, accessType, password and image - but unfortunately I have been having issues uploading images with the Next js api route. I have googled for hours and no result. I disabled the bodyParser to allow files to be read but that only made things worst. It could no longer read any data at all from the req.body. I am currently using postman for testing the API. I will be very grateful if someone could please help me out before I lose my mind.
import multer from "multer";
import dbConnect from "/utils/dbConnect";
import path from "path";
import Manager from "/models/Manager";
dbConnect();
export const config = {
api: {
bodyParser: false
}
}
const manager = async (req, res) => {
const {method} = req;
const { name, email, accessType, password } = req.body;
// const { filename } = req.file;
// console.log(filename);
console.log(name, email, accessType, password, "values");
switch(method) {
case "POST":
try {
}
catch(error) {
}
res.status(200).json({success: true, name});
}
}
export default manager;
I am building out a webpage which needs to make a call to the Google Geocoder api.
In order to hide the api key from public view, I am trying to set up server middleware to act as a REST api endpoint.
I have checked through all of the documentation and copied all of it, but the response is always the same. I receive the entirety of the html body back from the axios request rather than anything else I send back via express.
In my component I have the following code:
computed: {
normalizedAddress() {
return `${this.member.address.street} ${this.member.address.city}, ${this.member.address.state} ${this.member.address.zip}`.replace(
/\s/g,
'+'
)
}
},
methods: {
async getLocation() {
try {
const res = await axios.get(
`/api/geocode/${this.normalizedAddress}`
)
console.log(res)
} catch (err) {
console.log(err)
}
}
},
In nuxt.config.js I have this setup
serverMiddleware: ['~/api/geocode.js'],
In the root of my project I have an api folder with geocode.js stored there.
geocode.js is below
import express from 'express';
import axios from "axios";
let GEO_API = "MY_API_KEY"
const app = express();
app.use(express.json());
app.get("/", async (req, res) => {
const uri = `https://maps.googleapis.com/maps/api/geocode/json?address=${req.params.address}&key=${GEO_API}`
try {
const code = await axios.get(uri);
if (code.status !== "OK") {
return res.status(500).send(code.status)
}
return res.status(200).send(code);
} catch (err) {
return res.status(500).send(err);
}
});
export default {
path: "/api/geocode/:address",
handler: app
}
Again. The response always has the entire html document from the website sent back (some 100 pages of code).
Even when I set the response to fixed text, that is not sent.
The only detail I can think of that might be interrupting it is that I have my own custom routing setup using the #nuxtjs/router build module in use.
I'm creating a web application using React / Aws Amplify as the front end and AWS API-Gateway and S3 in the back end and Cognito as our user authentication. I have a page where the user needs to submit a form and a file. I was able to set this up for text files but once I started to work on binary files bad things happened.
I build the API in AWS and tested it using Postman as well as Curl and I'm able to post binary files. When I make the call through Amplify it stops working. I can make the call through Axios but then I need to turn off the Authentication, hence why I'm trying to do this through amplify. I also do not want to use amplify storage as it does not meet my needs. What typically happens is the file size is larger then the file sent and when I download it out of S3 it does not work any longer.
import React, { Component } from "react";
import "./Dashboard.css";
import { API } from "aws-amplify";
import { saveAs } from 'file-saver';
import axios from 'axios';
export default class Home extends Component {
uploadLambda = async (event) => {
//This one work if I turn off User Authentication
let file = event.target.files[0];
let reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = async () => {
try
{
return axios({
method: 'POST',
url: 'https://XXXXXXXXXX.execute-api.us-east-1.amazonaws.com/dev/upload',
headers: {
'Content-Type': 'application/pdf'
},
data: reader.result
});
}
catch(e)
{
console.log(e);
}
}
}
uploadImageLambda = async(event) => {
//This is the one I'm trying to get to work with binary files
var file_name = event.target.files[0].name;
console.log('Saving File Via Lambda: ' + file_name);
var reader = new FileReader();
reader.readAsDataURL(event.target.files[0]);
//reader.readAsBinaryString(event.target.files[0]);
//reader.readAsArrayBuffer(event.target.files[0]);
reader.onload = async () =>
{
try
{
/**
Someone suggested this but it does not fix the problem
let encoded = reader.result.toString().replace(/^data:(.*,)?/, '');
if ((encoded.length % 4) > 0) {
encoded += '='.repeat(4 - (encoded.length % 4));
}
console.log(encoded);
//"isBase64Encoded": "true",
**/
return await API.post("lambdadocshell", 'upload', { 'headers': { 'Content-Type': 'application/pdf', }, 'body': reader.result });
}
catch (e)
{
console.log(e);
}
}
}
render() {
return (
<div className="FileTest">
<h1>Upload A File</h1>
<form onSubmit={this.handleSubmit} enctype="multipart/form-data">
Select File: <input type="file" onChange={this.uploadLambda} />
</form>
</div>
);
}
}
In the code above you can see 2 upload functions, both hit the same API-Gateway. uploadLambda works but only if authentication on the API-Gateway is turned off. uploadImageLambda does not work regardless of authentication. We do use the Amplify in a number of other pages to move JSON back and forth to the API without issues. You can also see commented code as we tried a number of different ways to get amplify to work.
After talking with AWS support, they said that amplify apparently does a JSON.stringify to the data which then increases the length of the file. Currently there does not seem to be a workaround for this issue. As such they suggested that I use Axios to make the request to API Gateway. Hopefully this will be resolved in the future.
I am attempting to use the Apollo GraphQL Client for React Native. However, in some parts of my app I need to do a mutation on the GraphQL data, in such a way that the interface should not be exposed to the user.
For instance, on my sign up page, I want to create a user in the database, but only after I have gone through and verified everything, created a uuid, etc. (things that require a class). If the call is sucessful, I want to imediately move on to the home page of the app. If not, I want to notify the user.
As such, I need access to do a GraphQL request, without hooks and just using callbacks to change the UI. Is this possible, and how could this be done?
The documentation does a bad job of explaining it, but you can simply call query or mutate on the ApolloClient object. https://www.apollographql.com/docs/react/api/core/ApolloClient/#apolloclient-functions
Compared to the other answer, this is probably better than making a raw call with just fetch because it uses the same cache layer as the rest of your application, instead of going around it.
const apolloClient = new ApolloClient({
uri: "/graphql",
cache: new InMemoryCache()
})
const qr = gql`
query {
getCustomers() {
name
}
}
`
const result = await apolloClient.query({
query: qr ,
variables: {}
})
Yes, its possible.
A call to the GraphQL service simply expects a key-value pair of query or mutation in the body with the query/mutation you're trying to send.
You can do this with a simple fetch request as POST, or a cURL, or via postman... It doesn't really matter as long as its a POST request.
See also here.
Yes, It is possible as a matter of fact I am leaving sample classes that can be used for both query and mutation.
First, configure your application to work with graphQl.
Wrap your app with the provider.
import { client } from './config/connection';
import { ApolloProvider } from '#apollo/client';
<ApolloProvider client={client}>
<App/>
</ApolloProvider>
Here is the client that we want to
import { ApolloClient, ApolloLink, InMemoryCache } from '#apollo/client';
export const client = new ApolloClient({
cache: new InMemoryCache(),
uri: 'http://localhost:4000/graphql',
});
Operations.js (Contains Queries And Mutations gql)
import { gql } from '#apollo/client';
export const Query_SignIn = gql`
query Login($email: String!, $password: String!) {
login(email: $email, password: $password) {
name
}
}
`;
export const Mutate_SignUp = gql`
mutation SignUp($name: String!, $email: String!, $password: String!, $passwordConfirmation: String!) {
signUp(name: $name, email: $email, password: $password, passwordConfirmation: $passwordConfirmation) {
name
}
}
`;
A Class using query instead of useQuery hook
import { Query_SignIn } from '../../../operations';
class login {
constructor(client) {
this._client = client;
}
async signIn(email, password) {
const response = await this._client.query({
query: Query_SignIn,
variables: {
email,
password,
},
});
return response;
}
}
export default login;
A class using mutate instead of useMutation
import { Mutate_SignUp } from '../../../operations';
class register {
constructor(client) {
this._client = client;
}
async signUp(accountType, name, email, password, passwordConfirmation) {
const response = await this._client.mutate({
mutation: Mutate_SignUp,
variables: {
name,
email,
password,
passwordConfirmation,
},
});
return response;
}
}
export default register;