Can I use the multer module as middleware? - express

In my post path handler I currently have this:
const upload = multer();
// response handler for posting to /upload
app.post("/upload", upload.single('file'), function (request: any, response: any, next: any) {
// do stuff
}
That adds a file property on the request.body that contains the uploaded file.
IIUC this approach applies to this specific express post function. But can I have it use as middleware using the use function? Or can I call it manually inline?
// use function
app.use("/upload", upload);
// use it inline
app.post("/upload", function (request: any, response: any, next: any) {
upload.single('file');
// do stuff
}

Related

Redefine $fetch in nuxt3 with global onRequest handler

Is it possible to use global onRequest handler to $fetch with Nuxt3, to add specific data on each request?
With nuxt2 and axios it was simple
/plugins/axios.js
export default function ({ $axios, store, req }) {
$axios.onRequest((config) => {
if (config.data) {
config.data.test = '123';
} else {
config.data = { test: '123' };
}
return config;
});
}
But how achieve same goal on Nuxt3 and $fetch?
Ok, so Nuxt3 $fetch documentation says:
Nuxt uses ofetch to expose globally the $fetch helper...
When we jump into ofetch documentation we can see the Interceptors section. This gives us some options to do what you are trying to achieve. My suggestion is this:
Create a http composable (or anyother name you wish):
// composables/use-http.js
const opts = {
async onRequest({ request, options }) {
// Add your specific data here
options.query = { t: '1234' }
options.headers = { 'Authorization': 'my_token' }
}
}
export default () => $fetch.create(opts)
And here we are making usage of the onRequest interceptor from ofetch
onRequest is called as soon as ofetch is being called, allowing to modify options or just do simple logging.
There you can add any data you want, if you need you can create the logic to pass parameters to this composable and so on...
Now, to actually fetch the data (use the composable):
const http = useHttp() // useHttp is auto-imported
const data = await http('/url') // will trigger the interceptor

how to use asynchronous error handlers in onError callback?

I'm creating a link to remove user auth token on a 401 response from server. The problem here, is that I need to remove tokesn from storage in my case AsyncStorage, which, as its name suggests, performs asynchronous operations, but if I try to pass an asynchronous function to onError callback from #apollo/client/link/error, the code editor immediately throws the following error: Type 'Promise<void>' is not assignable to type 'void | Observable<FetchResult<{ [key: string]: any; },.
So there is a way to pass an async callback to onError?
Invalidate token link
import {ErrorResponse, onError} from '#apollo/client/link/error';
import {isJwtError, JWTError} from './errors';
// async function to remove auth token from asyncstorage
import {removeTokens} from './utils';
interface ResponseError extends ErrorResponse {
networkError?: Error & {
statusCode?: number;
bodyText?: string;
};
}
export const invalidateTokenLink = onError((error: ResponseError) => {
if (
(error.networkError && error.networkError.statusCode === 401) ||
error.graphQLErrors?.some(isJwtError)
) {
if (error.graphQLErrors[0].extensions.code !== JWTError.expired) {
// this is where I run an asynchronous function to remove the token
removeTokens();
}
}
});
The error message mentions that you can return an Observable<FetchResult<{ [key: string]: any; }. It seems that apollo-client uses the zen-observable library.
You can build an observable from your promise. Or use the promiseToObservable function from observable-helpers.

Fetch API not showing json data

I am relatively new to react native and trying to build an app and am using the fetch API to try and get a json file from the api. My problem is that it seems to not have any response when i make the calls to the api.
Here is the function that contains the fetch calls
export const fetchData = url => {
return async dispatch => {
dispatch(fetchingRequest());
try {
let response = await fetch(url);
let json = response.json();
console.log(json);
dispatch(fetchingSuccess(json));
} catch (error) {
dispatch(fetchingFailure(error));
}
};
};
The console.log(json) does not come up when I check in the chrome debugger.
if the url is needed for reference, I used https://randomuser.me/api/.
This function is called in one of my other components. I am also using redux and redux-thunk to store the data in the JSON file.
Edited in:
I believe the problem to be the function is not being executed when called.
I import the function and all the redux actions like this
import {
fetchingSuccess,
fetchingRequest,
fetchingFailure,
fetchData
} from "../data/redux/actions/appActions.js";
The fetchData function is then called in a _onPress function that is written like this
_onPress = () => {
let url = "https://randomuser.me/api/?results=10"
fetchData(url);
console.log("should have fetched");
};
in the console the expected output should be the
JSON contents or error // logged when fetchData is called
should have fetched // logged from _onPress
but instead the console outputs
should have fetched // logged from _onPress
The problem is that response.json() returns a promise, so when you do:
let json = response.json();
Without the await then the log after is still a promise, in order for this to work you must add the await in front of the response.json():
let json = await response.json();
The json() method of the Body mixin takes a Response stream and reads
it to completion. It returns a promise that resolves with the result
of parsing the body text as JSON.

Forward fetch response headers to Apollo graphql response

I have an apollo-datasource-rest data source setup on an Apollo/Graphql
Expressjs server. I'd like to forward a few headers from the fetch response to the /graphql response.
Here is the flow:
POST /graphql
Graphql makes fetch request using this.get('http://example.com/api')
Response from this fetch contains the header "cache-status"
Response from /graphql
I'd like to include the "cache-status" header from the example.com/api response here in the /graphql response
I see the header in the didReceiveResponse() method of the rest datasource class. I'm not sure this is the right place to access and store it. How do I include the "cache-status" header in the POST /graphql response?
Assuming you're RESTDataSource from apollo-datasource-rest, you can override the didReceiveResponse to intercept the response and return a custom return value.
Here's a code snippet in Typescript, it can be easily converted to Javascript if need be by removing the parameter/return types and access modifiers.
class MyRestDataSource extends RESTDataSource {
public constructor(baseUrl: string) {
super();
this.baseURL = baseUrl;
}
public async getSomething(): Promise<any & { headers?: { [key: string]: string } }> {
// make the get request
return this.get('path/to/something');
}
// intercept response after receiving it
protected async didReceiveResponse(response: Response, _request: Request) {
// get the value that is returned by default, by calling didReceiveResponse from the base class
const defaultReturnValue = await super.didReceiveResponse(response, _request);
// check if it makes sense to replace return value for this type of request
if (_request.url.endsWith('path/to/something')) {
// if yes get the headers from response headers and add it to the returned value
return {
...defaultReturnValue,
headers: { headerValue: response.headers.get('header_name') },
};
}
return defaultReturnValue;
}
}
I think you can utilize formatResponse of ApolloServerLambda()
And respond with proper headers. I have not tried it myself. But looking at the document I feel it should be helpful
formatResponse?: (
response: GraphQLResponse,
requestContext: GraphQLRequestContext<TContext>,
) => GraphQLResponse | null;

Typescript overwrite express send function with hybrid interface

I'm trying to overwrite the node express send method of the Response type.
The method is of type Send that is defined as such:
interface Send {
(status: number, body?: any): Response;
(body?: any): Response;
}
My objective is to add local logging of the response send with express, but I can't make an implementation of this type, even as a function like explained in other questions like this.
That interface describes a function with two signatures, you can implement it like so:
const fn: Send = (first?: any, second?: any) => {
if (first && second) {
// deal with (status: number, body: any)
} else if (first) {
// deal with (status: number) or (body: any)
} else {
// deal with ()
}
return new Response();
}