I need to output data from the json file that the user loads at the front.
I download the json file, but I get a strange store in Redux and can not figure out how to further display the data to the screen from the store.
What should I need to do?
import React from 'react'
import { connect } from 'react-redux'
import * as actions from './actions'
class File extends React.Component {
constructor (props) {
super(props)
}
handleChange (e) {
e.preventDefault();
let reader = new FileReader();
let file = e.target.files[0];
reader.onloadend = () => {
let text = reader.result;
this.props.jsonLoad(JSON.parse(text))
}
reader.readAsText(file)
}
render () {
return (
<div>
<h3> Add your file: </h3>
<input type="file" multiple onChange={this.handleChange.bind(this)}/>
<button >
add text from file
</button>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
json: state.json
}
}
function mapDispatchToProps (dispatch) {
return {
jsonLoad: (json) => dispatch(actions.jsonLoad(json)),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(File)
action.js
const USER_JSON = 'USER_JSON';
export function jsonLoad(json) {
console.log( json)
return function (dispatch) {
let file = json
dispatch(addFile(file))
}
}
export function addFile (json) {
return{
type: 'USER_JSON',
payload: json
}
};
Related
i wrote this code to get data from json using nextjs
this is the json file:
json file data
import styled from "styled-components";
import type { GetStaticProps, NextPage } from "next";
import { randomUUID } from "crypto";
type PageProps = {
apiData:string
}
const Home: NextPage<PageProps> = ({ apiData }) => {
return <div>
{JSON.stringify(apiData) }
{
apiData.map((i,index)=>{
i.map((e)=>{
return (<div key={index}>
<p>{i.title}</p>
</div>)
})
})
}
</div>;
};
the error is Property 'map' does not exist on type 'string'.ts(2339)
This happens because apiData is defined as a string (line 6 in your example) and therefore does not contain a method map in its prototype. The method map exists only for arrays.
Try changing the type for your PageProps or parse your JSON-string and make sure that your data is an array.
...
type PageProps = {
apiData: any[]
}
...
Or parse the string to JSON.
const Home: NextPage<PageProps> = ({ apiData }) => {
const parsedData = apiData ? JSON.parse(apiData) : null;
if (parsedData === null) {
throw new Error("apiData is not defined.");
}
return (
<div>
{apiData}
{
parsedData.map((i, index) => {
i.map((e) => {
return (<div key={index}>
<p>{i.title}</p>
</div>)
})
})
}
</div>
);
};
I am new to Shopify App development and I try to implement routing inside my embedded Shopify App.
I have setup the ClientRouter and also integrated it inside the app.js (see below). When I set Navigation Links through the partners Account, the navigation menu appears and the links and the redirecting work as well.
As soon as I try to navigate the user to a page on a Button click, I get the error:
Expected a valid shop query parameter
I am trying to navigate the user by just giving the path for the page:
<Button url="/users">Users</Button>
My other files are listed below:
index.js
import { Page, Heading, Button } from "#shopify/polaris";
const Index = () => (
<Page>
<Heading>Index PAGE</Heading>
<Button url="/users"> Users </Button>
</Page>
);
export default Index;
app.js
import ApolloClient from "apollo-boost";
import { ApolloProvider } from "react-apollo";
import App from "next/app";
import { AppProvider } from "#shopify/polaris";
import { Provider, useAppBridge } from "#shopify/app-bridge-react";
import { authenticatedFetch } from "#shopify/app-bridge-utils";
import { Redirect } from "#shopify/app-bridge/actions";
import "#shopify/polaris/dist/styles.css";
import translations from "#shopify/polaris/locales/en.json";
import ClientRouter from "../components/ClientRouter";
function userLoggedInFetch(app) {
const fetchFunction = authenticatedFetch(app);
return async (uri, options) => {
const response = await fetchFunction(uri, options);
if (
response.headers.get("X-Shopify-API-Request-Failure-Reauthorize") === "1"
) {
const authUrlHeader = response.headers.get(
"X-Shopify-API-Request-Failure-Reauthorize-Url"
);
const redirect = Redirect.create(app);
redirect.dispatch(Redirect.Action.APP, authUrlHeader || `/auth`);
return null;
}
return response;
};
}
function MyProvider(props) {
const app = useAppBridge();
const client = new ApolloClient({
fetch: userLoggedInFetch(app),
fetchOptions: {
credentials: "include",
},
});
const Component = props.Component;
return (
<ApolloProvider client={client}>
<Component {...props} />
</ApolloProvider>
);
}
class MyApp extends App {
render() {
const { Component, pageProps, host } = this.props;
return (
<AppProvider i18n={translations}>
<Provider
config={{
apiKey: API_KEY,
host: host,
forceRedirect: true,
}}
>
<ClientRouter />
<MyProvider Component={Component} {...pageProps} />
</Provider>
</AppProvider>
);
}
}
MyApp.getInitialProps = async ({ ctx }) => {
return {
host: ctx.query.host,
API_KEY: process.env.SHOPIFY_API_KEY,
};
};
export default MyApp;
ClientRouter.js
import { withRouter } from "next/router";
import { ClientRouter as AppBridgeClientRouter } from "#shopify/app-bridge-react";
function ClientRouter(props) {
const { router } = props;
return <AppBridgeClientRouter history={router} />;
}
export default withRouter(ClientRouter);
I am really looking forward to someone who can help me out! Thanks in advance!
I am working on kepler.gl .... wright now i am reading data from an api and plot that data in keplr.gl and that's working fine here is the code ...
import keplerGlReducer from "kepler.gl/reducers";
import { createStore, combineReducers, applyMiddleware } from "redux";
import { taskMiddleware } from "react-palm/tasks";
import { Provider, useDispatch } from "react-redux";
import KeplerGl from "kepler.gl";
import { addDataToMap } from "kepler.gl/actions";
import useSwr from "swr";
const reducers = combineReducers({
keplerGl: keplerGlReducer
});
const store = createStore(reducers, {}, applyMiddleware(taskMiddleware));
export default function App() {
return (
<Provider store={store}>
<Map />
<csv/>
</Provider>
);
}
function Map() {
const dispatch = useDispatch();
const { data } = useSwr("covid", async () => {
const response = await fetch(
"https://gist.githubusercontent.com/leighhalliday/a994915d8050e90d413515e97babd3b3/raw/a3eaaadcc784168e3845a98931780bd60afb362f/covid19.json"
);
const data = await response.json();
return data;
});
React.useEffect(() => {
if (data) {
dispatch(
addDataToMap({
datasets: {
info: {
label: "COVID-19",
id: "covid19"
},
data
},
option: {
centerMap: true,
readOnly: false
},
config: {}
})
);
}
}, [dispatch, data]);
return (
<KeplerGl
id="covid"
mapboxApiAccessToken="pk.eyJ1IjoiYWxpcmF6YTcwNSIsImEiOiJjazh5d2hjb3AwOHBqM2VsY21wOHo5eXprIn0.9G5CE4KqfbvU9HQ6WBuo3w"
width={window.innerWidth}
height={window.innerHeight}
/>
);
}
now i want to read data from jason or csv file and plot that data into kepler.gl map .. how can i do this can anyone help me ?..... thanks
In React do it like this
import datajson from './yourdata.json';
const data=datajson;
easiest way would be to place your json or csv file beside your code and
import your json file:
const dataJson = require('./data.json');
change your data source to your json:
const data = dataJson
// or dataJson.data depending on your json structure
or if your data is in csv format the fastest way that comes to mind is installing the csv-parse and then:
const data = parse(csvData, {
//config based on your csv format
columns: true,
skip_empty_lines: true
});
hope this is what you are looking for
This is the api http://skunkworks.ignitesol.com:8000/books/ ,
I am trying to fetch the array results from it using the fetch method but instead get an error cannot fetch value of undefined
import React, { Component } from 'react';
class App extends Component {
constructor() {
super()
this.state = {
books: []
}
}
componentDidMount() {
fetch('http://skunkworks.ignitesol.com:8000/books/')
.then(res => res.json())
.then(data => this.setState({ books: data }))
.catch(e => {
console.log(e);
return e;
});
}
render() {
let book = []
book = this.state.books.results;
console.log(book[0])
return (
<div>
<h1>Books</h1>
</div>
)
}
}
export default App;
this is my code.
Also I have observed that json data are usually like [{}] but here it is {} format.
please suggest me some solution.....
As I see from your url link, you json array of data is present in the results key of the returned object from the API.
So if you're only interested by the results you should do something like that :
import React, { Component } from 'react';
class App extends Component {
state = {
books: []
}
async componentDidMount() {
const objectFromUrl = await fetch('http://skunkworks.ignitesol.com:8000/books/')
const data = await objectFromUrl.json() //first way
// or you can use destructuring way
const { results } = await objectFromUrl.json() //second way
this.setState({
books: data.results // results key contains your '[{}]' data an array of objects
})
}
render() {
const { books } = this.state
return (
<div>
<h1>Books</h1>
{books.map(book => (
<h2> {book.id} </h2>
)}
</div>
);
}
// You can use destructuring again to get only key you're interested by
render() {
const { books } = this.state
return (
<div>
<h1>Books</h1>
{books.map(({id, formats}) => (
<h2> {id} </h2>
<h2> { formats[ˋapplication/pdf’] } </h2>
)}
</div>
);
}
}
I have create a page with different input elements with file upload. While saving the form with multiple files along with form input elements using angular 6, the file object is empty {} in console an http service in network tab.
Here is my code:
onFileChanged(event) {
this.selectedFiles = event.target.files;
const uploadData = new FormData();
uploadData.append('myFile', this.selectedFiles, this.selectedFiles[0].name);
this.createFormData.attachment = uploadData;
};
Can anyone provide a sample to help me?
This is example of upload method in service. Pass files and input values from component to service, create formData, loop on files and append each file to formData and same with input values.
upload(files, inputs) {
let formData = new FormData();
files.map((file) => {
formData.append('file', file);
});
inputs.map((input) => {
formData.append(`${input.name}`, input.value);
});
return this.http.post(`some/api/upload`, formData)
.pipe(map((res) => res.data));
}
With this example your request should contain all array of files and inputs, also if you need some special header add it after formData in post method (in my case i handle headers in interceptor).
upload(files, inputs) {
let formData = new FormData();
files.map((file) => {
formData.append('file', file);
});
inputs.map((input) => {
formData.append(`${input.name}`, input.value);
});
const headers = new HttpHeaders({
'Accept': 'application/json'
});
const options = { headers: headers };
return this.http.post(`some/api/upload`, formData, options)
.pipe(map((res) => res.data));
}
Have a look at following example with npm's ng2-file-upload (in this case with a fontAwsome-icon).
myFileUploadForm.component.html:
<!-- file upload -->
<input #fileToUpload type="file" style="display:none;" ng2FileSelect (change)="onFileChanged($event)" [uploader]="uploader"
name="customerFile" id="customerFile" class="customerFile" />
<a href="javascript:document.getElementById('customerFile').click();">
<fa class="ql-upload" *ngIf="buttonDeaktivieren" [title]="'Upload'" [name]="'upload'" [size]="0.9" [border]=false></fa>
</a>
myFileUploadForm.component.ts (I'll ommit the obvious parts with ..):
import { Component, OnInit, ViewChild, OnDestroy, TemplateRef } from '#angular/core';
import { Subscription, Observable } from '../../../../../node_modules/rxjs';
....
...
import { FileUploader } from 'ng2-file-upload';
#Component({
....
...
..
})
export class myFileUploadFormComponent implements OnInit, OnDestroy {
public uploader: FileUploader = new FileUploader({ url:
'http://localhost:3000/files/uploadFile/', itemAlias: 'customerFile' });
filesArray = [];
constructor(
...
..
private http: Http
) { }
ngOnInit() {
....
...
..
}
// INFO: Function for opening confirm modal when deleting file
openDeleteFileModal(file) {
const initialState = {
file: file
};
this.deleteFileModalRef = this.modalService.show(ConfirmFileDeletionComponent, {
initialState, class: 'modal-md modal-dialog-centered' });
}
// INFO: Handy helper for assigning appropriate file-icon according to extension
getFilesIcon(file) {
if (file === 'docx') {
return 'file-word-o';
} else if (file === 'jpeg' || file === 'jpg' || file === 'png') {
return 'image';
} else if (file === 'pdf') {
return 'file-pdf-o';
} else if (file === 'xlsx' || file === 'xls') {
return 'file-excel-o';
} else if (file === 'pptx') {
return 'file-powerpoint-o';
} else if (file === 'zip') {
return 'file-archive-o';
} else {
return 'file';
}
}
/* INFO : service for downloading the uploaded file */
downloadFile(filename) {
this.fileDataService.downloadFile(filename);
}
onFileChanged(event) {
this.uploader.onBuildItemForm = (fileItem: any, form: any) => {
form.append('id', this.customer.id);
form.append('customername', this.customer.customername);
};
this.uploader.uploadAll();
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
Obviously this is my implementation suited to my needs (uploaded files are related to a certain customer and are displayed with icons according to extension and listed for future download or deletion as well), but I'm sure you can get it done by adjusting the code to your needs and write the relevant services. Have a nice one weekend ;)