Sending multiple .get() requests with Storyblok-nuxt - promise

Can someone please guide me regarding sending multiple .get() requests with Storyblok-nuxt?
I'm trying to do something like this:
context.app.$storyapi.all([requestOne, requestTwo]).then(
context.app.$storyapi.spread((...responses) => {
const responseOne = responses[0];
const responseTwo = responses[1];
console.log(responseOne, responseTwo, responesThree);
}));
Thanks.

Since the JS client of Storyblok is using an axios wrapper you can do it like this:
import axios from 'axios';
const requestOne = context.app.$storyapi.get('cdn/stories' + 'health', { version: "published" })
const requestTwo = context.app.$storyapi.get('cdn/datasources', { version: "published" })
const requestThree = context.app.$storyapi.get('cdn/stories' + 'vue', { version: "published" })
axios.all([requestOne, requestTwo, requestThree]).then(axios.spread((...responses) => {
const responseOne = responses[0]
const responseTwo = responses[1]
const responesThree = responses[2]
// use/access the results
})).catch(errors => {
// react on errors.
})
Here is also a full tutorial on this: https://www.storyblok.com/tp/how-to-send-multiple-requests-using-axios

Related

Upload image to server using expo-file-system

In a react native app, I am following the documentation of expo-file-system to upload an image from the gallery of my phone and send it to a node.js server that uses multer to process the file. Unfortunately, I am having the following error when I send the http request:
Possible Unhandled Promise Rejection (id: 1):
Error: Failed to connect to localhost/127.0.0.1:3000
I know that the server is working because I have tested it with the same client but using axios and fetch to send the request and it reached the server.
This is the code that I am using in the client side:
//.env
URL = 'http://localhost:3000/api/upload'
//uploadImage.js
import React, { useState } from "react";
import { View, Button, Image, StyleSheet } from "react-native";
import * as ImagePicker from 'expo-image-picker'
import * as FileSystem from 'expo-file-system';
import {URL} from "#env"
const ImageUpload = ()=>{
const [image, setImage] = useState('')
const [name, setName] = useState('')
const [type, setType] = useState('')
const openImageLibrary = async()=>{
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
console.log('this is the result',result);
if (!result.canceled) {
const uri = result.assets[0].uri
const filename = uri.split('/').pop();
const match = /\.(\w+)$/.exec(filename);
const imageType = match ? `image/${match[1]}` : `image`;
setImage(uri);
setName(filename)
setType(imageType)
}
}
const sendPictureToServer = async()=>{
const response = await FileSystem.uploadAsync(URL ,image,{
fieldName: 'photo',
httpMethod: 'POST',
uploadType: FileSystem.FileSystemUploadType.BINARY_CONTENT,
})
}
return(
<View>
<Button title = 'select' onPress={openImageLibrary}/>
<Button title='send' onPress={sendPictureToServer}/>
</View>
)
}
This is the node.js server
//index.js
const Express = require('express')
const multer = require('multer')
const bodyParser = require('body-parser')
const app = Express()
app.use(bodyParser.json())
const upload = multer({ dest: 'uploads/' } )
app.get('/', (req, res) => {
res.status(200).send('You can post to /api/upload.')
})
app.post('/api/upload', upload.single('photo'), (req, res) => {
console.log('file', req.file)
console.log('body', req.body)
res.status(200).json({
message: 'success!',
})
})
app.listen(3000, () => {
console.log('App running on http://localhost:3000')
})

Dynamic axios request url in Vue 3 Composables

I've tried this and it worked:
const posts = ref{[]}
const urlEndPoint = 'posts'
const getPosts = async () => {
let response = await axios.get('/api/'+urlEndPoint)
posts.value = response.data.data
}
but that one is not dynamic. My goal is to make the urlEndPoint value reactive and set from the components
then i tried this:
const urlEndPoint = ref([])
but I don't know how to send the value of urlEndPoint constant back from the component to the composables.
I tried these in my component:
const urlEndPoint = 'posts'
and
const sendUrlEndPoint = () => {
urlEndPoint = 'posts'
}
but none worked.
is there a way to accomplish this goal? like sending the component name to urlEndPoint value in composable or any other simple way.
Define a composable function named use useFetch :
import {ref} from 'vue'
export default useFetch(){
const data=ref([])
const getData = async (urlEndPoint) => {
let response = await axios.get('/api/'+urlEndPoint)
data.value = response.data.data
}
return {
getData,data
}
in your component import the function and use it like :
const urlEndPoint=ref('posts')
const {getData:getPosts, data:posts}=useFetch()
getPosts(urlEndPoint.value)

How to use SSR with Redux in Next.js(Typescript) using next-redux-wrapper? [duplicate]

This question already has an answer here:
next-redux-wrapper TypeError: nextCallback is not a function error in wrapper.getServerSideProps
(1 answer)
Closed 1 year ago.
Using redux with SSR in Next.js(Typescript) using next-redux-wrapper, but getting error on this line
async ({ req, store })
Says, Type 'Promise' provides no match for the signature '(context: GetServerSidePropsContext<ParsedUrlQuery, PreviewData>): Promise<GetServerSidePropsResult<{ [key: string]: any; }>>
Property 'req' does not exist on type 'Store<EmptyObject & { filterReducer: never; }, any> & { dispatch: unknown; }'.
Property 'store' does not exist on type 'Store<EmptyObject & { filterReducer: never; }, any> & { dispatch: unknown; }'
Here is my SSR code:-
export const getServerSideProps: GetServerSideProps = wrapper.getServerSideProps(async ({ req, store }) => {
let { query } = req
let searchCategory = query.category?.toString().toLowerCase().replace(/ /g, "-");
const apolloClient = initializeApollo();
const response = await apolloClient.query({
query: GET_PRODUCT_BY_CATEGORY,
variables: {
numProducts: 10,
category: searchCategory
}
});
await store.dispatch(getProducts(response));
});
You're calling wrapper.getServerSideProps in a wrong way.
Try like the following:
export const getServerSideProps = wrapper.getServerSideProps(
store => async ({req, res, query}) => {
// do your stuff with store and req
}
);
If you're looking for a working demo, you can visit my old answer
This code base could help you. ("next": "10.1.3")
Try using getInitialProps instead of getServerSideProps.
This works in my case. Like code below:
Try
in _app.js
import { wrapper } from '/store';
function MyApp(props) {
const { Component, pageProps } = props;
...
return (
<Component {...pageProps} />
)
}
App.getInitialProps = async props => {
const { Component, ctx } = props;
const pageProps = Component.getInitialProps
? await Component.getInitialProps(ctx)
: {};
//Anything returned here can be accessed by the client
return { pageProps: pageProps, store: ctx.store };
};
export default wrapper.withRedux(App);
store.js file:
const makeStore = props => {
if (!isEmpty(props)) {
return createStore(reducer, bindMiddleware([thunkMiddleware]));
} else {
const { persistStore, persistReducer } = require('redux-persist');
const persistConfig = {
key: 'root',
};
const persistedReducer = persistReducer(persistConfig, reducer); // Create a new reducer with our existing reducer
const store = createStore(
persistedReducer,
bindMiddleware([thunkMiddleware])
); // Creating the store again
store.__persistor = persistStore(store); // This creates a persistor object & push that persisted object to .__persistor, so that we can avail the persistability feature
return store;
}
};
// Export the wrapper & wrap the pages/_app.js with this wrapper only
export const wrapper = createWrapper(makeStore);
in your page:
HomePage.getInitialProps = async ctx => {
const { store, query, res } = ctx;
};

Migrating to 3.5.0 with apollo-server-express

I'm trying to update the version of one of my projects from node 12.x.x to node.14.x.x.
Now I saw the documentation of apollo to migrate to the v3 but it's not clear at all someone know where to start? Is it gonna be easier to make all the apollo part systems from scratch?
Current file that should be updated:
const { ApolloServer } = require('apollo-server-express');
const { makeExecutableSchema } = require('graphql-tools');
const { applyMiddleware } = require('graphql-middleware');
const { gql } = require('apollo-server-express');
const { resolvers, typeDefs } = require('graphql-scalars');
const { types } = require('./typedefs/types');
const { inputs } = require('./typedefs/inputs');
const { queries } = require('./typedefs/queries');
const { mutations } = require('./typedefs/mutations');
const customResolvers = require('./resolvers');
const { permissions } = require('./permissions/permissions');
const graphqlApis = gql`
${types}
${queries}
${inputs}
${mutations}
`;
const schema = makeExecutableSchema({
typeDefs: [...typeDefs, graphqlApis],
resolvers: {
...customResolvers,
...resolvers,
},
});
const server = new ApolloServer({
context: ({ req }) => {
const headers = req.headers || '';
return headers;
},
schema: applyMiddleware(schema, permissions),
});
module.exports = server;
Current error when trying to run: Error: You must 'await server.start()' before calling 'server.applyMiddleware()'
I would simply love to get some solutions/help/insight with it.
As mentioned in the docs, you need to surround your code with an Async function
https://www.apollographql.com/docs/apollo-server/migration/
(async function () {
// ....
})();
Or Like so: ...
define your typeDefs & resolvers first
const typeDefs = "" // your typedefs here
const resolvers = "" // your resolvers here
async function startApolloServer(typeDefs, resolvers) {
// Apollo Express 3.5.x code goes here
// ....
await server.start();
// promise resolve...
}
startApolloServer(typeDefs, resolvers)

hi, is there a way to get pdf document thru apollo2angular and graphql?

following is the response info:
"%PDF-1.4\n%����\n2 0 obj\n<>stream\nx��X�s�F\u0010�\u0019����$\u0010JaF\u000f\t\t�*:Iw�:�h������-ڀg/}]�yk��Z\u0002��0Vڈ��&��\n��ɐֳ�L\u0012?�4\u000bi���\u001b�D\u0017\tPقYl���\u0019p\u0010:\-g���Oǜ�F�\u0019�L�&�_c6�'\u0016��cv���fhm�ҏ?;�ǴK�U��d\u0007�!����qG{,k�M��\u001e۬�)-�E�GU¢\u0019�\u0003(�����q2R�\u001c%K�vC���[�;�j\u0004�E�PO�hH��dk\u0011\fN����騈���\u000fs=8���9\u001fY�\u00185t\u001d��A0Sa��!\u000e��i\u000f�(1R�q����>�\u0017�i��\u0017<�$��\u0015�;�|/^�;���v̺H\u0019�1�\t�#��m�?�\u00137q�\u0004�\\u0010ְ'M鴨\u000b���0�9B1�ێ���=�K,Z\"'���\u0019���3��W\u0010q\u0000A�D��� �Hh���\u0017�c�k��̉�i�W\u000b�Mph�P�#��0W:ʥ\u0003�*ӕ�9���\u0015OG��\u000e�$A)>�\u0018H*�R�1 7��~ch\u001a�CUfQ�j�9��+��K��Џ�\u001a{�G��)\f�D\u0012\f���(C\u0005��?ݗ��m�������c��0Ϩ�v#*#Hp�\u0019�Y�!��7�-�\u001b�a�w�3��&�T0q=�K�-ؚ�\u0018\u000e�)���]N�P\u0019ZB.�$w\u0015�\u0006n�&6|
Hey yes there is but it takes a little custom work!
Here is how you can do it to work with scaphold.io but you could extend this to your own implementation as well!
Basically what is happening is you attach the file at the root level of a multipart/form-data request and then from the input in your GraphQL variables you point to the key of the file in the request. Here is some code to show how you can retrofit and ApolloClient instance with a file-ready network interface that you can then feed into Angular2Apollo.
import { createNetworkInterface } from 'apollo-client';
// Create a file-ready ApolloClient instance.
export function makeClientApolloFileHandler() {
const graphqlUrl = `https://scaphold.io/graphql/my-app`;
const networkInterface = createNetworkInterface(graphqlUrl);
networkInterface.query = (request) => {
const formData = new FormData();
// Parse out the file and append at root level of form data.
const varDefs = request.query.definitions[0].variableDefinitions;
let vars = [];
if (varDefs && varDefs.length) {
vars = varDefs.map(def => def.variable.name.value);
}
const activeVars = vars.map(v => request.variables[v]);
const fname = find(activeVars, 'blobFieldName');
if (fname) {
const blobFieldName = fname.blobFieldName;
formData.append(blobFieldName, request.variables[blobFieldName]);
}
formData.append('query', printGraphQL(request.query));
formData.append('variables', JSON.stringify(request.variables || {}));
formData.append('operationName', JSON.stringify(request.operationName || ''));
const headers = { Accept: '*/*' };
if (localStorage.getItem('scaphold_user_token')) {
headers.Authorization = `Bearer ${localStorage.getItem('scaphold_user_token')}`;
}
return fetch(graphqlUrl, {
headers,
body: formData,
method: 'POST',
}).then(result => result.json());
};
const clientFileGraphql = new ApolloClient({
networkInterface,
initialState: {},
});
return clientFileGraphql;
}
After this function does its work on the request you might have FormData that looks like this (if it were encoded in JSON):
{
"query": "mutation CreateFile($input:CreateFileInput) { createFile(input: $input) { ... }",
"variables": {
"input": {
"blobFieldName": "myFile",
"name": "MyFileName!"
}
},
// Note how the blobFieldName points to this key
"myFile": <Buffer of file data in multipart/form-data>
}
The server would then need to understand how to interpret this in order to look for the file in the payload and associate it with the correct object etc.
Hope this helps!

Resources