i have an up and running api from GraphCMS.
i am building a small static website and want with Gatsby and i wanna take some data from GraphCMS with Graphql client (https://github.com/prismagraphql/graphql-request)
problem is that i am getting a types.js:24 Uncaught (in promise) Error: GraphQL Error (Code: 200) while doing the following:
My index.js
import React from 'react'
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
import { GraphQLClient } from 'graphql-request'
import Header from '../components/header'
import './index.css'
export default () =>
<div style={{ color: `tomato` }}>
<h1>Hello Gatsby!</h1>
<p>What a world.</p>
</div>
const client = new GraphQLClient('my-endpoint', {
headers: {
Authorization: 'mytokenfromGraphCms',
},
})
const query = `{
allCurrentEvents{
tip
awayteam
hometeam
date
}
allPasteventses{
tip
}
}`
client.request(query).then(data => console.log(data))
any thoughts?
thanks a lot
Did you allow read permissions for the fields you are querying? Or are you using a token? Can you actually post the error response you get from the request?
Related
Having trobule implementing okta redirect with docusaurus using their documentation due to how docusaurus intiallly loads in routes. Can anyone provide any guidance on how to go about this?
https://github.com/okta/okta-react
Expected Behavior:
Initial path to load up redirects to okta and authenticates then returns back to webpage.
I ran into this same issue and saw your posting hoping for an answer. bummer. Then I dug around a little more. It's not fully implemented yet because I'm waiting on the okta creds from my administrators, but this got me to a permission denied screen (which is a good thing to me!)
Few things:
docusaurus currently uses react-router-dom v5. you need to specifically set that instead of defaulting to v6
src/pages/index.tsx (i'm using typescript) should allow you to setup a browserrouter there
react-router-dom package:
"react-router": "^5.3.3",
"react-router-config": "^5.1.1",
"react-router-dom": "^5.3.3"
src/pages/index.tsx - I updated the home component to have a DocusaurusHome component, then made Home hold the routing logic
import React from 'react';
import clsx from 'clsx';
import Link from '#docusaurus/Link';
import useDocusaurusContext from '#docusaurus/useDocusaurusContext';
import Layout from '#theme/Layout';
import HomepageFeatures from '#site/src/components/HomepageFeatures';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import styles from './index.module.css';
import { OktaAuth } from '#okta/okta-auth-js';
import { Security, LoginCallback } from '#okta/okta-react';
import { RequiredAuth } from '../components/RequiredAuth';
// file with client id
import clientId from '../Okta/OktaClientID';
// file with issuer url
import issuerUrl from '../Okta/OktaIssuerUrl';
const config = {
clientId: clientId,
issuer: issuerUrl,
redirectUri: `${location.protocol}//${location.host}/callback`,
scopes: ['openid', 'profile', 'email'],
pkce: true
};
const oktaAuth = new OktaAuth(config);
function HomepageHeader() {
const {siteConfig} = useDocusaurusContext();
return (
<header className={clsx('hero hero--primary', styles.heroBanner)}>
<div className="container">
<h1 className="hero__title">{siteConfig.title}</h1>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link
className="button button--secondary button--lg"
to="/docs/intro">
Docusaurus Tutorial - 5min ⏱️
</Link>
</div>
</div>
</header>
);
}
/**
* Actual Docusaurus Home component
*/
function DocusaurusHome(): JSX.Element {
const {siteConfig} = useDocusaurusContext();
return (<Layout
title={`Hello from ${siteConfig.title}`}
description="Description will go into a meta tag in <head />">
<HomepageHeader />
<main>
<HomepageFeatures />
</main>
</Layout>)
}
/**
* component for react-router-dom browserrouter and okta auth
*/
export default function Home(): JSX.Element {
const restore = async (_oktaAuth: OktaAuth, originalUri: string) => {
window.location.replace(originalUri);
};
return (
<BrowserRouter>
<Security oktaAuth={oktaAuth} restoreOriginalUri={restore}>
<Switch>
<Route path='/callback'>
<LoginCallback
errorComponent={(err) => {
// eslint-disable-next-line no-console
console.error(err);
setTimeout(() => {
localStorage.removeItem('okta-token-storage');
window.location.replace(`${location.protocol}//${location.host}/`);
}, 2000);
return null;
}}/>
</Route>
<Route path='/'>
<RequiredAuth />
</Route>
<Route path='*'>
<DocusaurusHome />
</Route>
</Switch>
</Security>
</BrowserRouter>);
}
The RequiredAuth component originally returned an react-router-dom Outlet, which doesn't exist in v5. I think that a Route should suffice in it's place
import React, { useEffect } from 'react';
import { useOktaAuth } from '#okta/okta-react';
import { toRelativeUrl } from '#okta/okta-auth-js';
import { Route } from 'react-router-dom';
export const RequiredAuth: React.FC = () => {
const { oktaAuth, authState } = useOktaAuth();
useEffect(() => {
if (!authState) {
return;
}
if (!authState?.isAuthenticated) {
const originalUri = toRelativeUrl(window.location.href, window.location.origin);
oktaAuth.setOriginalUri(originalUri);
oktaAuth.signInWithRedirect();
}
}, [oktaAuth, !!authState, authState?.isAuthenticated]);
if (!authState || !authState?.isAuthenticated) {
return <></>; // loading screen before okta login
}
return (<Route />);
};
I am building a Vue3 app with the composition API. Installed it correctly. In my template is a button (just for testing purpose):
<button #click="getToken"> get token </button>
When I click this button I can see in the chrome developer tools (network tab) that this Graphql mutation is executed and is respponding correctly.
<script setup>
import { useQuery, useMutation } from "#vue/apollo-composable";
import gql from "graphql-tag";
const { mutate: getToken} = useMutation(gql`
mutation login {
login(
authProfileUuid: "1234567"
username: "email#company.com"
password: "secret"
) {
jwtToken
}
}
`,)
</script>
My problem is that i just can't figure out how to get access to the JSON data in the response. Its my first time using apollo and can't find it in the docs. Can anyone help me ?
Martijn D.
Hey you should change your code to this:
<script setup>
import { useQuery, useMutation } from "#vue/apollo-composable";
import gql from "graphql-tag";
const { mutate: getToken, onDone } = useMutation(gql`
mutation login {
login(
authProfileUuid: "1234567"
username: "email#company.com"
password: "secret"
) {
jwtToken
}
}
`);
onDone((res) => {
console.log(res);
});
</script>
I am rather new to Gatsby. I am using Strapi as backend and in my frontend Gatsby, in the GraphQL playground I am executing the following query with expected outcome:
query MyQuery {
strapiAssessment {
title
rating {
id
topic
rate
}
}
}
In my Gatsby frontend code I have the following:
import React from "react"
import Title from "../components/Title"
import { graphql } from "gatsby"
const SelfAssesment = ({ data }) => {
const {
strapiAssessment: { title, rating },
} = data
console.log(data)
return (
<section className="section jobs">
<Title title={title} />
<div className="about-stack">
<p>Rankning i olika teknologier:</p>
{rating.map(item => {
return <span key={item.id}>{item.topic}</span>
})}
</div>
<div className="about-stack">
{rating.map(item => {
return <span key={item.id}>{item.rate}</span>
})}
</div>
</section>
)
}
export const query = graphql`
{
strapiAssessment {
title
rating {
id
topic
rate
}
}
}
`
export default SelfAssesment
I am getting the following error:
I am getting undefined, do I have something undeclared or a typo somewhere?
You are running a page query in a component that is not in a top-level (components/SelfAssesment). As you can see from the docs:
Querying data with a Page Query
You can use the graphql tag to query data in the pages of your Gatsby
site. This gives you access to anything included in Gatsby’s data
layer, such as site metadata, source plugins, images, and more.
Querying data with the StaticQuery Component
StaticQuery is a component for retrieving data from Gatsby’s data
layer in non-page components, such as a header, navigation, or any
other child component.
That said, you have two options here. Use the query in a top-level component (page) and drill-down the props down to the component or use a StaticQuery (or useStaticQuery hook).
I have a device that sends a heartbeat to my Apollo GraphQL server every 30 seconds. I have a React component that subscribes to hbReceived, and displays the most recent heartbeat time. This works fine.
BUT,
If my GraphQL server is down, I want to handle that error. I expect these errors to be returned in the useSubscription() hook's return value error.networkError property. Instead, I just see client.ts:545 WebSocket connection to 'ws://localhost:4000/graphql' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED in the console, and the error key remains undefined in the useSubscripiton response.
schema.graphql:
type Heartbeat {
id: ID!
heartbeatTime: DateISO8601!
deviceId: ID!
}
type Subscription {
heartbeatReceived(chargePointInstallId: ID!) : Heartbeat
hbReceived(deviceId: ID!): Heartbeat
}
I made a simple version of my app in create-react-app to illustrate this problem:
src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Heartbeat from './Heartbeat';
import { ApolloProvider } from 'react-apollo';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { WebSocketLink } from 'apollo-link-ws';
const link = new WebSocketLink({
uri: 'ws://localhost:4000/graphql',
options: {
reconnect: true,
}
});
const client = new ApolloClient({
link,
cache: new InMemoryCache()
});
ReactDOM.render(
<React.StrictMode>
<ApolloProvider client = {client}>
<Heartbeat deviceId={1} />
</ApolloProvider>
</React.StrictMode>,
document.getElementById('root')
);
src/Heartbeat.js
import React from 'react';
import './App.css';
import { useSubscription } from 'react-apollo';
import gql from 'graphql-tag';
export default function Heartbeat(props) {
const { loading, data, error} = useSubscription(
gql`
subscription hbReceived($deviceId: ID!) {
hbReceived(deviceId: $deviceId) {
heartbeatTime
}
}`,
{ variables:{ deviceId: `${props.deviceId}`}}
);
let mostRecentHeartbeatTimeStr;
if (error) {
console.log('Error rerturned:');
console.log(error);
mostRecentHeartbeatTimeStr = 'See console for error';
} else if (loading) {
mostRecentHeartbeatTimeStr = 'Waiting for first heartbeat';
} else {
const mostRecentHeartbeatDate = new Date(data.heartbeatReceived.heartbeatTime);
mostRecentHeartbeatTimeStr = 'Last Heartbeat: ' + mostRecentHeartbeatDate.toLocaleString('en-AU',{})
}
return (<div className='device'>
<div className='device-heading'>
Device heartbeat:
</div>
<div className='device-row'>
{mostRecentHeartbeatTimeStr}
</div>
</div>)
}
This is what I see in the console when the graphQL server is down:
WebSocket connection to 'ws://localhost:4000/graphql' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
How do I catch that WebSocket ERR_CONNECTION_REFUSED error and display some nice message to my user?
What I have tried
I have put a connectionCallback in the options for the new WebSocketLink constructor
parameters(url,{ options: { connectionCallback(error) => { console.log(error);} });
I have tried composing a link with an onError from import { onError } from "apollo-link-error"; in it, and put { errorPolicy: 'all' } in my useSubscription call.
The documentation also says the default behaviour is that network errors are treated like GraphQL errors.
I am stuck! Any help appreciated!
I have a Laravel app and I am using vue.js and vue-authenticate to have a user login with their Microsoft account. The vue.js app is living under a laravel route not Laravel home page i.e. if the homepage route is / then the vueapp route is /vueapp.
On the vueapp's home page I have the Login with Microsoft button configured. In my vue app the base url is set to mydomain/vueapp. I can successfully authorize the app with my Microsoft account but then instead of being able to see a success message and a token, I see the following error:
Error: Request failed with status code 405
I have Axios and Vuex installed and my vue routes are supported in the hash mode instead of history because of some weird laravel issue.
Update: I am seeing a similar issue with Google. It seems like something happens when the URI is redirected.
Update: Below is my code:
For my component:
<script>
import store from '../store'
import axios from 'axios'
export default{
data () {
return {
}
},
methods: {
authenticate: function (provider) {
console.log("Login Started" + provider);
this.$auth.authenticate(provider).then((response) => {
console.log("Login Successful " + response);
}).catch(error => {
console.log("error occured ");
console.log(error);
})
}
},
}
</script>
My HTML ---
auth Live
auth Google
In my app.js
import Vue from 'vue'
import lodash from 'lodash'
import VueLodash from 'vue-lodash'
import VueAxios from 'vue-axios'
import VueAuthenticate from 'vue-authenticate'
import Vuex from 'vuex'
import App from './App.vue'
import router from './router'
import axios from 'axios'
Vue.use(VueLodash, lodash)
Vue.use(require('vue-moment'));
import vmodal from 'vue-js-modal'
Vue.use(vmodal, {
dialog: true,
dynamic: true,
})
import Toasted from 'vue-toasted';
Vue.use(Toasted, 'top-center')
Vue.use(VueAxios, axios)
Vue.use(Vuex)
import VueAuthenticate from 'vue-authenticate'
Vue.use(VueAuthenticate, {
baseUrl: 'https://www.mywebsite.com', // Your API domain
providers: {
live: {
clientId: 'My Mcirosoft key',
redirectUri: 'https://www.mywebsite.com/auth/live' // Your client app URL
},
google: {
clientId: 'mygooglekey.apps.googleusercontent.com',
redirectUri: 'https://www.mywebsite.com/auth/google'
}
}
})
In laravel - I have the following routes. Webapp is the folder where vue app lives and it uses the hash mode for routing not history.
Route::get('webapp/{path?}', function () {
return View::make('app');
})->where( 'path', '([A-z\d-\/_.]+)?' );
Route::get('auth/live', function () {
return View::make('app');
});
Route::get('auth/google', function () {
return View::make('app');
});