From df065e9657495ea211a6c0d67a485ad6fe08365f Mon Sep 17 00:00:00 2001 From: Faraz Patankar Date: Thu, 14 May 2020 18:20:48 -0400 Subject: [PATCH 1/5] add with-apollo example --- with-apollo/App.js | 14 +++++++++ with-apollo/README.md | 21 ++++++++++++++ with-apollo/RootComponent.js | 56 ++++++++++++++++++++++++++++++++++++ with-apollo/apollo.js | 24 ++++++++++++++++ with-apollo/package.json | 25 ++++++++++++++++ 5 files changed, 140 insertions(+) create mode 100644 with-apollo/App.js create mode 100644 with-apollo/README.md create mode 100644 with-apollo/RootComponent.js create mode 100644 with-apollo/apollo.js create mode 100644 with-apollo/package.json diff --git a/with-apollo/App.js b/with-apollo/App.js new file mode 100644 index 0000000..43420ff --- /dev/null +++ b/with-apollo/App.js @@ -0,0 +1,14 @@ +import React from 'react'; +import { ApolloProvider } from '@apollo/client'; + +import { apolloClient } from './apollo'; + +import RootComponent from './RootComponent'; + +export default function App() { + return ( + + + + ); +} diff --git a/with-apollo/README.md b/with-apollo/README.md new file mode 100644 index 0000000..5959db2 --- /dev/null +++ b/with-apollo/README.md @@ -0,0 +1,21 @@ +# Apollo GraphQL Example + +

+ + Supports Expo iOS + + Supports Expo Android + + Supports Expo Web +

+ +## 🚀 How to use + +- Install with `yarn` or `npm install`. +- Run `expo start` to try it out. + +## 📝 Notes + +- The Apollo configuration lies in the `apollo.js` file. +- The file also contains an option (with commented code) to pass an authorization token to the API. +- [Apollo Client Docs](https://www.apollographql.com/docs/react/v3.0-beta/) diff --git a/with-apollo/RootComponent.js b/with-apollo/RootComponent.js new file mode 100644 index 0000000..f7ce843 --- /dev/null +++ b/with-apollo/RootComponent.js @@ -0,0 +1,56 @@ +import React from 'react'; +import { Text, View, SafeAreaView, ActivityIndicator, Image } from 'react-native'; +import { useQuery, gql } from '@apollo/client'; + +const GET_TWEET = gql` + query { + twitter { + tweet(id: "1261034643710775299") { + text + user { + name + screen_name + profile_image_url + } + } + } + } +` + +const RootComponent = () => { + const { data, loading, error } = useQuery(GET_TWEET); + + if (error) console.error('error', error) + if (loading) return ( + + + + ) + const { tweet } = data.twitter; + const { user } = tweet; + return ( + + + + + + {user.name} + + + @{user.screen_name} + + + + + + {tweet.text} + + + + ) +} + +export default RootComponent; diff --git a/with-apollo/apollo.js b/with-apollo/apollo.js new file mode 100644 index 0000000..16cba29 --- /dev/null +++ b/with-apollo/apollo.js @@ -0,0 +1,24 @@ +import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client'; +// import { setContext } from '@apollo/link-context'; + +const GRAPHQL_API_URL = 'https://www.graphqlhub.com/graphql'; +// const TOKEN = ''; + +// const asyncAuthLink = setContext(async () => { +// return { +// headers: { +// Authorization: TOKEN, +// }, +// }; +// }); + +const httpLink = new HttpLink({ + uri: GRAPHQL_API_URL, +}); + +export const apolloClient = new ApolloClient({ + cache: new InMemoryCache(), + link: httpLink, + // use this when using with auth token + // link: asyncAuthLink.concat(httpLink), +}); diff --git a/with-apollo/package.json b/with-apollo/package.json new file mode 100644 index 0000000..fde9b97 --- /dev/null +++ b/with-apollo/package.json @@ -0,0 +1,25 @@ +{ + "main": "node_modules/expo/AppEntry.js", + "scripts": { + "start": "expo start", + "android": "expo start --android", + "ios": "expo start --ios", + "web": "expo start --web", + "eject": "expo eject" + }, + "dependencies": { + "@apollo/client": "^3.0.0-beta.48", + "@apollo/link-context": "^2.0.0-beta.3", + "expo": "~37.0.3", + "graphql": "^15.0.0", + "react": "~16.9.0", + "react-dom": "~16.9.0", + "react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz", + "react-native-web": "~0.11.7" + }, + "devDependencies": { + "@babel/core": "^7.8.6", + "babel-preset-expo": "~8.1.0" + }, + "private": true +} From ecd3a4d1a255749d4d6bb6047edfaa61be4833fa Mon Sep 17 00:00:00 2001 From: Faraz Patankar Date: Thu, 14 May 2020 18:32:05 -0400 Subject: [PATCH 2/5] clean up package.json --- with-apollo/RootComponent.js | 6 +++--- with-apollo/package.json | 14 ++------------ 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/with-apollo/RootComponent.js b/with-apollo/RootComponent.js index f7ce843..9a86584 100644 --- a/with-apollo/RootComponent.js +++ b/with-apollo/RootComponent.js @@ -17,15 +17,15 @@ const GET_TWEET = gql` } ` -const RootComponent = () => { +function RootComponent() { const { data, loading, error } = useQuery(GET_TWEET); - if (error) console.error('error', error) + if (error) { console.error('error', error) }; if (loading) return ( - ) + ); const { tweet } = data.twitter; const { user } = tweet; return ( diff --git a/with-apollo/package.json b/with-apollo/package.json index fde9b97..50f6c56 100644 --- a/with-apollo/package.json +++ b/with-apollo/package.json @@ -1,12 +1,4 @@ { - "main": "node_modules/expo/AppEntry.js", - "scripts": { - "start": "expo start", - "android": "expo start --android", - "ios": "expo start --ios", - "web": "expo start --web", - "eject": "expo eject" - }, "dependencies": { "@apollo/client": "^3.0.0-beta.48", "@apollo/link-context": "^2.0.0-beta.3", @@ -18,8 +10,6 @@ "react-native-web": "~0.11.7" }, "devDependencies": { - "@babel/core": "^7.8.6", - "babel-preset-expo": "~8.1.0" - }, - "private": true + "@babel/core": "^7.8.6" + } } From a0e472f3b4da7d38c1abdbcd2fc4481c5706ae42 Mon Sep 17 00:00:00 2001 From: Faraz Patankar Date: Thu, 14 May 2020 18:40:05 -0400 Subject: [PATCH 3/5] refactor root component to use stylesheet --- with-apollo/RootComponent.js | 68 ++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/with-apollo/RootComponent.js b/with-apollo/RootComponent.js index 9a86584..a67e94e 100644 --- a/with-apollo/RootComponent.js +++ b/with-apollo/RootComponent.js @@ -1,5 +1,5 @@ import React from 'react'; -import { Text, View, SafeAreaView, ActivityIndicator, Image } from 'react-native'; +import { Text, View, SafeAreaView, ActivityIndicator, Image, StyleSheet } from 'react-native'; import { useQuery, gql } from '@apollo/client'; const GET_TWEET = gql` @@ -21,31 +21,33 @@ function RootComponent() { const { data, loading, error } = useQuery(GET_TWEET); if (error) { console.error('error', error) }; - if (loading) return ( - - - - ); + if (loading) { + return ( + + + + ); + }; const { tweet } = data.twitter; const { user } = tweet; return ( - - + + - - + + {user.name} - + @{user.screen_name} - - + + {tweet.text} @@ -53,4 +55,42 @@ function RootComponent() { ) } +const styles = StyleSheet.create({ + loadingContainer: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + container: { + flex: 1, + justifyContent: 'center', + paddingHorizontal: 50 + }, + profileContainer: { + flexDirection: 'row', + alignItems: 'center' + }, + image: { + height: 50, + width: 50, + borderRadius: 100, + }, + details: { + marginLeft: 5, + }, + name: { + fontSize: 20, + fontWeight: 'bold' + }, + username: { + color: 'gray' + }, + tweetContainer: { + marginTop: 10 + }, + tweet: { + fontSize: 16 + } +}); + export default RootComponent; From 4543c50fa1304b81781f4d7dbb44194839b341af Mon Sep 17 00:00:00 2001 From: Faraz Patankar Date: Thu, 14 May 2020 18:46:25 -0400 Subject: [PATCH 4/5] move root component into app.js --- with-apollo/App.js | 94 ++++++++++++++++++++++++++++++++++- with-apollo/RootComponent.js | 96 ------------------------------------ 2 files changed, 92 insertions(+), 98 deletions(-) delete mode 100644 with-apollo/RootComponent.js diff --git a/with-apollo/App.js b/with-apollo/App.js index 43420ff..56983a5 100644 --- a/with-apollo/App.js +++ b/with-apollo/App.js @@ -1,9 +1,99 @@ import React from 'react'; -import { ApolloProvider } from '@apollo/client'; +import { Text, View, SafeAreaView, ActivityIndicator, Image, StyleSheet } from 'react-native'; +import { ApolloProvider, useQuery, gql } from '@apollo/client'; import { apolloClient } from './apollo'; -import RootComponent from './RootComponent'; +const GET_TWEET = gql` + query { + twitter { + tweet(id: "1261034643710775299") { + text + user { + name + screen_name + profile_image_url + } + } + } + } +` + +function RootComponent() { + const { data, loading, error } = useQuery(GET_TWEET); + + if (error) { console.error('error', error) }; + if (loading) { + return ( + + + + ); + }; + const { tweet } = data.twitter; + const { user } = tweet; + return ( + + + + + + {user.name} + + + @{user.screen_name} + + + + + + {tweet.text} + + + + ) +} + +const styles = StyleSheet.create({ + loadingContainer: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + container: { + flex: 1, + justifyContent: 'center', + paddingHorizontal: 50 + }, + profileContainer: { + flexDirection: 'row', + alignItems: 'center' + }, + image: { + height: 50, + width: 50, + borderRadius: 100, + }, + details: { + marginLeft: 5, + }, + name: { + fontSize: 20, + fontWeight: 'bold' + }, + username: { + color: 'gray' + }, + tweetContainer: { + marginTop: 10 + }, + tweet: { + fontSize: 16 + } +}); export default function App() { return ( diff --git a/with-apollo/RootComponent.js b/with-apollo/RootComponent.js deleted file mode 100644 index a67e94e..0000000 --- a/with-apollo/RootComponent.js +++ /dev/null @@ -1,96 +0,0 @@ -import React from 'react'; -import { Text, View, SafeAreaView, ActivityIndicator, Image, StyleSheet } from 'react-native'; -import { useQuery, gql } from '@apollo/client'; - -const GET_TWEET = gql` - query { - twitter { - tweet(id: "1261034643710775299") { - text - user { - name - screen_name - profile_image_url - } - } - } - } -` - -function RootComponent() { - const { data, loading, error } = useQuery(GET_TWEET); - - if (error) { console.error('error', error) }; - if (loading) { - return ( - - - - ); - }; - const { tweet } = data.twitter; - const { user } = tweet; - return ( - - - - - - {user.name} - - - @{user.screen_name} - - - - - - {tweet.text} - - - - ) -} - -const styles = StyleSheet.create({ - loadingContainer: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - }, - container: { - flex: 1, - justifyContent: 'center', - paddingHorizontal: 50 - }, - profileContainer: { - flexDirection: 'row', - alignItems: 'center' - }, - image: { - height: 50, - width: 50, - borderRadius: 100, - }, - details: { - marginLeft: 5, - }, - name: { - fontSize: 20, - fontWeight: 'bold' - }, - username: { - color: 'gray' - }, - tweetContainer: { - marginTop: 10 - }, - tweet: { - fontSize: 16 - } -}); - -export default RootComponent; From 2f3ce764ecbb3323d9f5b699999f31490906c59e Mon Sep 17 00:00:00 2001 From: Faraz Patankar Date: Thu, 14 May 2020 18:51:32 -0400 Subject: [PATCH 5/5] add comment to explain authentication setup --- with-apollo/apollo.js | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/with-apollo/apollo.js b/with-apollo/apollo.js index 16cba29..97c4013 100644 --- a/with-apollo/apollo.js +++ b/with-apollo/apollo.js @@ -2,15 +2,23 @@ import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client'; // import { setContext } from '@apollo/link-context'; const GRAPHQL_API_URL = 'https://www.graphqlhub.com/graphql'; -// const TOKEN = ''; -// const asyncAuthLink = setContext(async () => { -// return { -// headers: { -// Authorization: TOKEN, -// }, -// }; -// }); +/* +uncomment the code below in case you are using a GraphQL API that requires some form of +authentication. asyncAuthLink will run every time your request is made and use the token +you provide while making the request. + + +const TOKEN = ''; +const asyncAuthLink = setContext(async () => { + return { + headers: { + Authorization: TOKEN, + }, + }; +}); + +*/ const httpLink = new HttpLink({ uri: GRAPHQL_API_URL, @@ -19,6 +27,5 @@ const httpLink = new HttpLink({ export const apolloClient = new ApolloClient({ cache: new InMemoryCache(), link: httpLink, - // use this when using with auth token // link: asyncAuthLink.concat(httpLink), });