ReactJS, Django , GraphQL - Uploading file - javascript

I am trying to upload a file in frontend and send the data to Django backend using graphql.
function Integrations() {
const [importTranscations] = useMutation(IMPORT_TRANSACTIONS);
function onChange({
target: {
validity,
files: [file],
},
}) {
if (validity.valid) {
importTranscations({ variables: { file } });
}
}
return (
<div
style={{
padding: "20px",
}}
>
<input type="file" required onChange={onChange} />
</div>
);
}
export default Integrations;
When I inspect the network tab and observe the graphql api call, I can observe that an empty object is being sent as 'file':
I have also added logs in the Django backend where I am using graphene-file-upload module. I am getting file as an empty Dictionary.
URLs:
from django.urls import path
from django.contrib import admin
from django.views.decorators.csrf import csrf_exempt
from graphene_file_upload.django import FileUploadGraphQLView
urlpatterns = [
path("admin/", admin.site.urls),
path("graphql/", csrf_exempt(FileUploadGraphQLView.as_view())),
]
Mutations:
import graphene
from graphene_file_upload.scalars import Upload
class ImportTransactionsMutation(graphene.Mutation):
class Arguments:
file = Upload(required=True)
task_id = graphene.String()
def mutate(self, info, file):
print("## DEBUGGING ## -> file", file)
task_id = "sample"
return ImportTransactionsMutation(task_id=task_id)
This is the output that I am seeing in the console:
## DEBUGGING ## -> file {}
Here is a link to codesandbox. You can open the network tab and check the graphql API.

Related

Undefined after console are homepage to see if we getting correct the data in inspect element [Solved]

The detail of the problem is that I'm not getting the data we expected within our code. We have set up the following to see within our project folder.
Within webpack.config.js we set up resolve.alias in the webpack configuration, so we can include it in the resolve object of the webpack config file.
This is the file:
module.exports = {
// other webpack config options
resolve: {
alias: {
// Create an alias for the queries folder
queries: path.resolve(__dirname, 'src/queries'),
},
},
};
This is what are path name will look like:
import { homeQuery } from "queries/navigation/homeLinks";
Created a webpack.config.js.
Console.log are data of homeData and HomeData.homelink.
Tested the query within GraphQL Playground in Hygraph.
From there I checked the console in the browser.
I have found out we are not getting the query in our body that we want but we have tested the query within GraphQL Playground. We have found out that we correctly getting the correct query that we want to get into our data within console.log.
This is a query for the homepage:
import { gql } from "#apollo/client";
export const homeQuery = gql`
query homeLinks {
pages(
where: {id: "clbzl7ovpe64d0ak5qh7o2p8f", slug: "Home"}
stage: PUBLISHED
locales: en
) {
id
slug
title
}
}`
;
This where we console are data for the homepage:
console.log(homeData && homeData?.homeLink?.pages);
console.log(homeData)
import React from 'react';
import '../assets/style/navigation.css';
import { useQuery } from '#apollo/client';
import { BrowserRouter as Router, Link } from 'react-router-dom';
import { homeQuery } from "../queries/navigation/homeLinks";
import { logoassetsQuery } from "../queries/navigation/logoLinks";
export default function App() {
const { loading: logoAssetsLoading, error: logoassetsData } = useQuery(logoassetsQuery);
//This is query for the pages.
const { loading: homeLoading, error: homeError, data: homeData } = useQuery(homeQuery);
//This is for front-end error message.
if (logoAssetsLoading) return <p>Loading Logo Assets...</p>;
if (homeLoading) return <p>Loading... this page links.</p>
if (homeError) return <p>Error :( this page don't work.</p>;
// Debugging step 1: Check the value of data.navigation
console.log(homeData && homeData.homeLinks)
console.log(homeData)
// Debugging step 2: Check the value of data
//console.log(data);
return (
<div className='navigation'>
<div className='full_width_container'>
<div className='wrapper'>
<Router>
<React.Fragment>
<nav>
<div className='nav_groups logo'>
{homeData && homeData?.homeLinks?.pages && homeData?.homeLinks?.page(link => (
<li key={link?.id}>
<Link to={`/${link?.slug}`}>
<img src={logoassetsData?.logoAssets} alt='main logo'/>
</Link>
</li>
))}
</div>
</nav>
</React.Fragment>
</Router>
</div>
</div>
</div>
);
}

How to use 'env' property in Nuxt.js to get newapi?

I try to make news web apps to use newsapi.org.
I wanted to hide my api_key so I decided to use env property in Nuxt.Js.
But now I got 401 status code from server.
first of all, I made the .env file in project file and I put my API_KEY.
and then I installed 'dotenv' use 'yarn add dotenv' command in VSCode terminal.
and I add nuxt.config.ts file. I have used TypeScript in my project so all file depend on TypeScript.
require('dotenv').config()
const { API_KEY } = process.env
export default {
~~~~~~~~~~
env: {
API_KEY,
},
}
and I used Vuex to get news information.
so I made code like following.
~/store/getNews.ts
import { MutationTree, ActionTree, GetterTree } from "vuex";
import axios from "axios";
const url = 'http://newsapi.org/v2/top-headlines';
interface RootState { }
export interface NewsArticles {
source?: {}
author?: string
title?: string
description?: string
url?: any
urlToImage?: any
publishedAt?: string
content?: string
}
interface State {
newArticle: NewsArticles
}
export const state = () => ({
newsArticle: []
})
export const getters: GetterTree<State, RootState> = {
newsArticle: (state: State) => state.newArticle
}
export const mutations: MutationTree<State> = {
setNewsArticle: (state: State, newsArticle: NewsArticles) => {
state.newArticle = newsArticle
}
}
export const actions: ActionTree<State, RootState> = {
getNewsArticle: async ({ commit },{params}) => {
try{
const data = await axios.get(url,{params})
commit('setNewsArticle', data.data.articles)
}catch(error){
commit('setNewsArticle',[])
}
}
}
export default { state, getters, mutations, actions }
and finally, I made vue file to show the news information like following.
<template>
<div>
<p>this is NewsApi test pages!!</p>
<ul v-for="(item, index) in items" :key="index">
<li>{{ item.title }}</li>
</ul>
</div>
</template>
<script lang="ts">
import { Component, namespace, Vue } from 'nuxt-property-decorator'
import { NewsArticles } from '~/store/getNews'
const getNews = namespace('getNews')
#Component({})
export default class extends Vue {
#getNews.Action getNewsArticle!: Function
#getNews.Getter newsArticle!: NewsArticles
items: any = []
async mounted() {
await this.getNewsArticle({
params: { country: 'jp', category: 'business', apiKey: process.env.API_KEY },
})
this.items = this.newsArticle
}
}
</script>
I ran my app but I got 401 status code and I checked the console error like following.
{status: "error", code: "apiKeyInvalid",…}
code: "apiKeyInvalid"
message: "Your API key is invalid or incorrect. Check your key, or go to https://newsapi.org to create a free API key."
status: "error"
I don't know why that error occurred.
I checked apikey correctly setting to confirm consle.log.
in index.vue
<script lang='ts'>
~~~~
export default class extend Vue{
mounted(){
console.log(process.env.API_KEY)
}
}
</script>
You don't need to call require('dotenv').config(), as Nuxt automatically invokes it.
Also, for the env vars to be available in the production build, their names must be prefixed with NUXT_ENV_ (i.e., NUXT_ENV_API_KEY). Note this allows you to keep the key from being checked into source (assuming your .env file is also kept out of source control), but your API key can still be observed in the Network tab in DevTools.

GatsbyJS - TypeError: Cannot read property 'childImageFluid' of undefined

I am working on a Gatsby website, and I keep getting "TypeError: Cannot read property 'childImageFluid' of undefined"
The code I have is this in my Project.js file
import React from "react"
import PropTypes from "prop-types"
import Image from "gatsby-image"
import { FaGithubSquare, FaShareSquare } from "react-icons/fa"
const Project = ({description, title, github, stack, url, image, index}) => {
return (
<article className="project">
<Image fluid={image.childImageFluid.fluid} className="project-img" />
</article>
)
}
Project.propTypes = {}
export default Project
and I have the graphql set up in the index.js file where it will be displayed, and everything is working as it should in graphql...
export const query = graphql`
{
allStrapiProjects(filter: { featured: { eq: true } }) {
nodes {
github
id
description
title
url
image {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
stack {
id
title
}
}
}
}
`
everything up to the what I am working on in the Project.js file is in my github - https://github.com/matthewbert86/gatsby-site but all of that code is in the first code section above.
When you use a page query in GraphQL, your gathered data is stored inside a data object (as a props). You need to iterate through it until you get your fluid image. It should be in: props.data.allStrapiProjects.nodes.image.childImageFluid.fluid. Since you are destructuring everything in your <Project> component:
const Project = ({ data }) => {
let { description, title, github, stack, url, image } = data.allStrapiProjects.nodes; // your data is here
return (
<article className="project">
<Img fluid={data.allStrapiProjects.nodes.image.childImageFluid.fluid} className="project-img" />
</article>
)
}
After destructuring, you can refactor it to:
<Img fluid={image.childImageFluid.fluid} className="project-img" />
Another point, I guess that the gatsby-image import should be Img, not Image.

No upload button using FilePond ReactJs

Good day,
I am wanting to Use FilePond with Reactjs to facilitate image uploads to a server.What I want is to have the file populate in the Pond like the description shows then for the upload button to appear for the user to upload the file.
Initially from using their demo code I noticed that it would auto-upload files and from reading the documentation I see that I disable that auto upload feature using "instantUpload={false}" in my server. However I have done this and I still don't have an upload button for the user to use. I read the documentation some more and they say I need to specify the server which I have . Is there something that I am missing to show the upload button in my code.
Code below:
import React, { Component } from "react";
/*import agent from "superagent";*/
import classNames from "classnames";
import cookie from 'react-cookies';
// Import React FilePond
import { FilePond, registerPlugin } from "react-filepond";
// Import FilePond styles
import "filepond/dist/filepond.min.css";
// Import the Image EXIF Orientation and Image Preview plugins
// Note: These need to be installed separately
import FilePondPluginImageExifOrientation from "filepond-plugin-image-exif-orientation";
import FilePondPluginImagePreview from "filepond-plugin-image-preview";
import "filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css";
// Register the plugins
registerPlugin(FilePondPluginImageExifOrientation, FilePondPluginImagePreview);
export default class FotoUpload extends Component {
constructor(props) {
super(props);
this.state = {
// Set initial files, type 'local' means this is a file
// that has already been uploaded to the server (see docs)
files: [
{
source: "index.html",
options: {
type: "local"
}
}
]
};
}
handleInit() {
console.log("FilePond instance has initialised", this.pond);
}
render() {
return (
<div className="App">
{/* Pass FilePond properties as attributes */}
<FilePond
ref={ref => (this.pond = ref)}
allowFilePoster={true}
instantUpload={false}
server=
{
{
url: 'http://mybackend.com:5000/upload/images',
process: {
headers: {
'cookie-token': cookie.load('cookie')
},
}
}
}
name="image"
acceptedFileTypes={['image/*']}
oninit={() => this.handleInit()}
onupdatefiles={fileItems => {
// Set currently active file objects to this.state
this.setState({
files: fileItems.map(fileItem => fileItem.file)
});
}}
/>
</div>
);
}
}
If I allow the instaupload feature the file will upload and success will return , but I will still not receive an Upload button.
Myimage
As you can see there isn't an upload button like shown in the offical documentation.
Similar problem
https://github.com/pqina/vue-filepond/issues/5
FilePond Documentation
https://pqina.nl/filepond/docs/patterns/api/server/
Official repo
https://github.com/pqina/react-filepond

Import static JSON data in React

I am trying to load static JSON data to my react app. But, it wan't allow me to load data.
I am using webpack version 4.26.1
It shows me following error:
SyntaxError: src/data/movieData.json: Unexpected token, expected ; (2:10)
1 | {
2 | "data": [
| ^
3 | {
4 | "id": 1,
5 | "title": "Freed",
My Code:
data/jsonResponse.json
{
"data": [
{
"id": 1,
"title": "Freed"
},
{
"id": 2,
"title": "Fifty"
}
]
}
main.js
import React, { Component } from 'react';
import Content from './Content';
import jsonResponse from './data/jsonResponse.json';
class Main extends Component {
render() {
return (
<div className="main">
<Content item={ jsonResponse } />
</div>
);
}
}
export default Main;
Content.js
import React from 'react';
const Content = () => {
const movies = this.props.item.data;
return (
movies.map(movie => {
return (
<span >{movie.title}</span>
);
})
)
}
export default Content;
Edited:
If i use js instead of JSON like:
const movies_data = {
"data": [
{
"id": 1,
"title": "Freed"
},
{
"id": 2,
"title": "Fifty"
}
]
}
export default movies_data;
and in Main.js file
import jsonResponse from './data/movieData';
Then in browser it shows following error.
Cannot read property 'props' of undefined
There are 2 workarounds for loading json files in a js file.
Rename your json file to .js extension and export default your json from there.
Since json-loader is loaded by default on webpack >= v2.0.0 there's no need to change your webpack configs.
But you need to load your json file as json!./data/jsonResponse.json (pay attention to json!)
EDIT:
Cannot read property 'props' of undefined
The reason you're getting this error is because you're trying to access this on a functional component!
Answer regarding edited question and Cannot read property 'props' of undefined error
You can't access this in functional components. props are passed as argument to functional components so please try this (Content.js file):
import React from 'react';
const Content = (props) => {
const movies = props.item.data;
return (
movies.map(movie => {
return (
<span >{movie.title}</span>
);
})
)
}
export default Content;
You have to add a JSON loader to import json files.
You need to check if in your Webpack config if exist an loader to JSON.
I recommend to use this loader.
https://www.npmjs.com/package/json-loader

Categories