i want to display JSON result in reactJs - javascript

This is my JSON result
Using Map function to display JSON array elements in reactJs.I have tried with the following code. I'm unable to get results and it says "Cannot read property '_currentElement' of null". Kindly help me to solve this.
import React, { Component } from 'react';
import Header from './js/components/Header';
import './App.css';
import './dist/css/bootstrap.css';
import cookie from 'react-cookie';
import Request from 'superagent';
import { browserHistory } from 'react-router';
export default class Performance extends Component {
constructor() {
super();
this.state = {
fullName : cookie.load('fullName'),
empId : cookie.load('empId'),
userResults : false
};
if(cookie.load('empId') === undefined ){
browserHistory.push('/login')
}
}
getInitialState(){
return {userResults:false};
}
componentDidMount() {
var self = this;
var url = 'http://192.168.1.93:8081/employee/dashboard';
Request
.get(url)
.query({ empId: this.state.empId })
.set('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8')
.set('Authorization', 'Basic aHJtczox')
.set('Accept', 'application/json')
.end(function(err, res){
self.setState({userResults: res.body});
console.log(self.state.userResults);
});
}
render() {
return (
<div>
<Header />
<div className="container ">
<form className="form-signin1">
<h2 className="form-signin-heading">Customer Orientation{this.props.userButtons}</h2>
<table className="table text-center" >
<thead>
<th >Deliverables</th>
</thead>
<tbody>
{
this.state.userResults.response.QuestionSection.map(function(res){
res.question.map(function(res1){
return (
<tr>
<td>{res1.question}</td>
</tr>
)
})
})
}
<tr><td>sdfsdf</td></tr>
</tbody>
</table>
<button className="btn btn-lg btn-primary btn-block" type="button">Sign in</button>
</form>
</div>
</div>
);
}
}

Since this.state.userResults.response doesn't exist initially you get this error. Its is better of performing a check before iterating. Also you need to return the result of inner map function too like
{
this.state.userResults.response && this.state.userResults.response.QuestionSection.map(function(res){
return res.question.map(function(res1){
return (
<tr>
<td>{res1.question}</td>
</tr>
)
})
})
}

Related

Why do I need to refresh the web page sometimes to see the data i retrieved from the api appear on my table? Angular 9

I created an API using asp.net and I used angular as my front end. I am able to get the data just fine but sometimes I would need to refresh the page once or a few more times in order to actually see the data on my table. I have absolutely no idea why this might be happening. I hope the code I have inserted below will be enough to find the solution to my problem
Here is typescript file of my table component
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import {DataService} from 'src/app/Services/data.service';
import {Anime} from 'src/app/Classes/anime';
import { NgModule } from '#angular/core';
import {MatDialog, MatDialogConfig } from '#angular/material/dialog';
import { DialogComponent } from 'src/app/dialog/dialog.component';
#Component({
selector: 'app-anime-table',
templateUrl: './anime-table.component.html',
styleUrls: ['./anime-table.component.css']
})
export class AnimeTableComponent implements OnInit {
AnimeArray : Anime[] = [] ;
data = false;
constructor(private router : Router,
private dataService : DataService,
private Dialog: MatDialog
) {}
ngOnInit(){
this.dataService.GetAnime()
.subscribe(data => data.forEach(element => {
var anime = new Anime();
anime.AnimeID = element.AnimeID;
anime.AnimeName = element.AnimeName;
anime.Anime_Description = element.Anime_Description;
this.AnimeArray.push(anime);
}))
}// ngOnInit
}//Export
Below is the html stuff
<br />
<button routerLink="/Dashboard" class="btn btn-primary">Go Home</button>
<button
routerLink="/CreateAnime"
class="btn btn-success"
style="margin-left: 15px;"
>
Add new Anime
</button>
<br />
<br />
<table class="table table-striped">
<thead>
<tr>
<th>Anime ID</th>
<th>Anime Name</th>
<th>Anime Description</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let anime of AnimeArray">
<td>{{ anime.AnimeID }}</td>
<td>{{ anime.AnimeName }}</td>
<td>{{ anime.Anime_Description }}</td>
<td>
<!-- <a [routerLink] = "['/Anime']" [queryParams] = "anime.AnimeID" class="btn btn-success"> Edit </a> -->
<button (click)="EditAnime(anime.AnimeID)" class="btn btn-success">
Edit
</button>
<button
(click)="DeleteAnime(anime.AnimeID, anime.AnimeName)"
style="margin-left: 15px;"
class="btn btn-danger"
>
Delete
</button>
</td>
</tr>
</tbody>
</table>
Here is a piece of the dataservice that gets the Anime information from the API i created.
import { Injectable } from '#angular/core';
import {HttpClient} from '#angular/common/http'
import {HttpHeaders} from '#angular/common/http';
import { from, Observable } from 'rxjs';
import {Anime} from '../Classes/anime';
#Injectable({
providedIn: 'root'
})
export class DataService {
url : string;
header : any;
option : any;
constructor(private http : HttpClient) {
this.url = 'http://localhost:50484/api/Values/';
const headerSettings: {[name: string]: string | string[]; } = {};
//this.header = new HttpHeaders(headerSettings);
this.header = {'Authorization' : 'bearer ' + localStorage.getItem('UserToken')}
let headers = new HttpHeaders({'Authorization' : 'bearer ' + localStorage.getItem('UserToken')})
this.option = {headers : headers};
}
GetAnime() : Observable<Anime[]> {
console.log(this.header);
const headers = {'Authorization' : 'bearer ' + localStorage.getItem('UserToken')}
return this.http.get<Anime[]>(this.url + 'GetAllAnime/' , {headers});
}
} // data service
P.S I am currently not seeing any errors in the browser console, the cmd or in visual studio code
Try map data first and replace the entire array, instead of pushing in the array.
ngOnInit() {
this.dataService.GetAnime().subscribe(data => data =>
(this.AnimeArray = data.map(element => {
var anime = new Anime();
anime.AnimeID = element.AnimeID;
anime.AnimeName = element.AnimeName;
anime.Anime_Description = element.Anime_Description;
return anime;
}))
);
} // ngOnInit

Transform a SPFX TS without JS framework to a React TS

I used yo #microsoft/sharepoint to created a webpart to display a list of items.
The solution was created without Javascript framework.
import { Version } from '#microsoft/sp-core-library';
import { BaseClientSideWebPart } from '#microsoft/sp-webpart-base';
import {
IPropertyPaneConfiguration,
PropertyPaneTextField
} from '#microsoft/sp-property-pane';
import { escape } from '#microsoft/sp-lodash-subset';
import styles from './GetSpListItemsWebPart.module.scss';
import * as strings from 'GetSpListItemsWebPartStrings';
import {
SPHttpClient,
SPHttpClientResponse
} from '#microsoft/sp-http';
import {
Environment,
EnvironmentType
} from '#microsoft/sp-core-library';
export interface IGetSpListItemsWebPartProps {
description: string;
}
export interface ISPLists {
value: ISPList[];
}
export interface ISPList {
ID:string;
Title: string;
Summary : string;
NewsCategory: string;
Created:string;
AttachmentFiles:{
Name:string;
Url:string;
ServerRelativeUrl: string;
}
}
export default class GetSpListItemsWebPart extends BaseClientSideWebPart<IGetSpListItemsWebPartProps> {
private _getListData(): Promise<ISPLists> {
return this.context.spHttpClient.get(this.context.pageContext.web.absoluteUrl + "/_api/lists/GetByTitle('News')/items?$select=*&$expand=AttachmentFiles",SPHttpClient.configurations.v1)
.then((response: SPHttpClientResponse) => {
return response.json();
});
}
private _renderListAsync(): void {
if (Environment.type == EnvironmentType.SharePoint ||
Environment.type == EnvironmentType.ClassicSharePoint) {
this._getListData()
.then((response) => {
this._renderList(response.value);
});
}
}
public titleurl(query:string){
var path="/Lists/News/DispForm.aspx?ID=";
var currdir=this.context.pageContext.web.absoluteUrl;
var result=currdir+path+query;
return result;
}
private _renderList(items: ISPList[]): void {
let html: string = '<table border=1 width=100% style="border-collapse: collapse;">';
html += '<th>ID</th><th>Title</th> <th>Summary</th><th>Created</th><th>Attachments</th>';
items.forEach((item: ISPList) => {
html += `
<tr>
<td>${item.ID}</td>
<td>${item.Title}</td>
<td>${item.Title}</td>
<td>${item.Created}</td>
<td>
<img src="${item.AttachmentFiles[0].ServerRelativeUrl}" width="300px" height="300px" />
</td>
</tr>
`;
});
html += '</table>';
const listContainer: Element = this.domElement.querySelector('#spListContainer');
listContainer.innerHTML = html;
}
public render(): void {
this.domElement.innerHTML = `
<div class="${ styles.getSpListItems }">
<div class="${ styles.container }">
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${ styles.row }">
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
<span class="ms-font-xl ms-fontColor-white">Welcome to SharePoint Modern Developmennt</span>
<p class="ms-font-l ms-fontColor-white">Loading from ${this.context.pageContext.web.title}</p>
<p class="ms-font-l ms-fontColor-white">Retrive Data from SharePoint List</p>
</div>
</div>
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
<div>NEWS List Items</div>
<br>
<div id="spListContainer" />
</div>
</div>`;
this._renderListAsync();
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel
})
]
}
]
}
]
};
}
}
This part was rendered successfully.
I then created a solution yo #microsoft/sharepoint
using the React option.
I am stuck on how to render the HTML documents.
Previous it as used to this.domElement, but it says It is not in the class.
I attempted to creating another class to render seems unsuccessful.
How to print the results?
import * as React from 'react';
import styles from './B.module.scss';
import { IBProps } from './IBProps';
import { escape } from '#microsoft/sp-lodash-subset';
import {
SPHttpClient,
SPHttpClientResponse
} from '#microsoft/sp-http';
import {
Environment,
EnvironmentType
} from '#microsoft/sp-core-library';
import * as ReactDOM from 'react-dom';
export interface ISPLists {
value: ISPList[];
}
export interface ISPList {
ID:string;
Title: string;
Summary : string;
NewsCategory: string;
Created:string;
AttachmentFiles:{
Name:string;
Url:string;
ServerRelativeUrl: string;
}
}
export default class B extends React.Component<IBProps, {}> {
public render(): React.ReactElement<IBProps> {
return (
<div className={ styles.b }>
<div id="spListContainer"></div>
<div className={ styles.container }>
<div className={ styles.row }>
<div className={ styles.column }>
<span className={ styles.title }>Welcome to SharePoint!</span>
<p className={ styles.subTitle }>Customize SharePoint experiences using Web Parts.</p>
<p className={ styles.description }>{escape(this.props.description)}</p>
</div>
</div>
</div>
</div>
);
}
}
export class shownews extends B{
constructor(prop){
super(prop);
public _getListData(): Promise<ISPLists> {
return this.context.spHttpClient.get(this.context.pageContext.web.absoluteUrl + "/_api/lists/GetByTitle('News')/items?$select=*&$expand=AttachmentFiles",SPHttpClient.configurations.v1)
.then((response: SPHttpClientResponse) => {
return response.json();
});
}
public _renderListAsync(): void {
if (Environment.type == EnvironmentType.SharePoint ||
Environment.type == EnvironmentType.ClassicSharePoint) {
this._getListData()
.then((response) => {
this._renderList(response.value);
});
}
}
public titleurl(query:string){
var path="/Lists/News/DispForm.aspx?ID=";
var currdir=this.context.pageContext.web.absoluteUrl;
var result=currdir+path+query;
return result;
}
private _renderList(items: ISPList[]): void {
let html: string = '<table border=1 width=100% style="border-collapse: collapse;">';
html += '<th>ID</th><th>Title</th> <th>Summary</th><th>Created</th><th>Attachments</th>';
items.forEach((item: ISPList) => {
html += `
<tr>
<td>${item.ID}</td>
<td>${item.Title}</td>
<td>${item.Title}</td>
<td>${item.Created}</td>
<td>
<img src="${item.AttachmentFiles[0].ServerRelativeUrl}" width="300px" height="300px" />
</td>
</tr>
`;
});
html += '</table>';
const listContainer = React.createElement('h1',{},html);
ReactDOM.render(listContainer, document.getElementById('spListContainer'));
this._renderListAsync();
}
}
}
I do apologize If there are many tutorials on SPFX, REACT JS on CRUD operations.
However, I clone it, attempted to npm install or npm i -g, none of the repositories work for me.
2020-01-28
Rewrote the code to get json directly. The html tags won't render
import * as React from 'react';
import styles from './A.module.scss';
import { IAProps } from './IAProps';
import { escape } from '#microsoft/sp-lodash-subset';
import { PageContext } from "#microsoft/sp-page-context";
import { HttpClient, IHttpClientOptions, HttpClientResponse, SPHttpClient, ISPHttpClientOptions, SPHttpClientResponse } from '#microsoft/sp-http';
import {
Environment,
EnvironmentType
} from '#microsoft/sp-core-library';
export interface ISPLists {
value: ISPList[];
};
export interface ISPList {
ID:string;
Title: string;
Summary : string;
NewsCategory: string;
Created:string;
AttachmentFiles:{
Name:string;
Url:string;
ServerRelativeUrl: string;
};
}
export default class A extends React.Component<IAProps, {}> {
public test:any=[];
public data:any=[];
public geturl(query:string){
var path="/Lists/News/DispForm.aspx?ID=";
var currdir=this.props.pagecontext.web.absoluteUrl;
var result=currdir+path+query;
return result;
}
private getListData(){
const opt: ISPHttpClientOptions = { headers: { 'Content-Type': 'application/json;odata=verbose' } };
return this.props.SPHttpClient.get(this.props.pagecontext.web.absoluteUrl + "/_api/lists/GetByTitle('News')/items?$select=*&$expand=AttachmentFiles",SPHttpClient.configurations.v1,opt)
.then((response: SPHttpClientResponse) => {
response.json().then((json: any) => {
for(let i=0;i<json.value.length;i++){
this.data.push(<div><tr>
<td>${json.ID}</td>
<td>${json.Title}</td>
<td></td>
<td>${json.Created}</td>
<td><img src="${json.AttachmentFiles.ServerRelativeUrl}" width="300px" height="300px" /></td>
</tr></div>);
}
});
});
}
/*
private renderList(item: ISPList[]): void {
item.forEach((item: ISPList) => {
this.data.push(`<tr>
<td>${item.ID}</td>
<td>${item.Title}</td>
<td></td>
<td>${item.Created}</td>
<td><img src="${item.AttachmentFiles.ServerRelativeUrl}" width="300px" height="300px" /></td>
</tr>`
);
})
console.log(this.data);
};
*/
/*
private push() {
this.test.push(1);
this.test.push(2);
this.test.push(3);
console.log(this.test);
}
*/
public render(): React.ReactElement<IAProps>{
this.getListData();
console.log(this.data);
return (
<div id="splist">
TEST
<table className={styles.container}>
<tr>
<th>ID</th><th>Title</th> <th>Summary</th><th>Created</th><th>Attachments</th>
</tr>
<tr>
<td></td>
<td>TITLE</td>
<td></td>
<td>Created</td>
<td>
</td>
</tr>
{this.data}
1234
</table>
</div>
);
}
}
2020-01-28 18:15
This Don't Work this.
If I .push (data);
The Table would have ); all over the place.
this.setState({ items:"<td>{item.ID}</td>
<td>{item.Title}</td>
<td>{item.Summary}</td>
<td>{item.Created}</td>
<td>{item.AttachmentFiles[0].ServerRelativeUrl}</td>" });
This do not work
this.Title.push(<span><td>{item.Title}</td></span>);
this.Url.push(<span><td>{item.AttachmentFiles[0].ServerRelativeUrl}</td></span>);
This Works
this.ID.push(item.ID); /* this.Title.push(<span><td>{item.Title}</td></span>); this.Url.push(<span><td>{item.AttachmentFiles[0].ServerRelativeUrl}</td></span>); */ this.forceUpdate();
If I use an array and use .push to send data including HTML tags
the follow screenshot shows the problem.
The Code
public renderList(item: ISPList[]): void {
item.forEach((item: ISPList) => {
this.data.push(<tr>);
this.data.push(<td>{item.ID}</td>);
this.data.push(<td>{item.Title}</td>);
this.data.push(<td>{item.AttachmentFiles[0].ServerRelativeUrl}</td>);
this.data.push(</tr>);
//some brackets...
2020-01-28 1956 Problem TR WITHIN TR
Problem: If I write the HTML tags and data in one line the tags will generate it self. But in the render method, I need to add a tag to wrap it will make my output incorrect format.
//some codes before to get the JSON data
this.data.push(<tr>
<td>{item.ID}</td>
<td>{item.Title}</td>
<td>{item.AttachmentFiles[0].ServerRelativeUrl}</td></tr>);
//some more codes
public render(): React.ReactElement<IAProps>{
return (
<div id="splist">
TEST
<table className={styles.container}>
<tr>
<th>ID</th>
<th>Title</th>
<th>Attachments</th>
</tr>
{this.data}
</table>
</div>
);
}
Firstly, you need to think about your solution in terms of components (having props or states) that you want to render. In context of your solution you can create a component lets say: 'GetandRenderListItems.tsx' and do all ' _getListData()' stuff. You can use 'componentDidMount()' life cycle hook to call _getListData() function everytime after the component is mounted. Then you need to write html template to render retrieved data (all what you have done in '_renderList()' method) have a look at below snippet to get an idea:
public render(): React.ReactElement<IyourcomponentsProps> {
return (
// your dynamic table html and you should not use inline style but define styles in
scss file and use them.
);
}
Then in your 'yourwebpart.ts' file you can render this component in render() method:
public render(): void {
const element: React.ReactElement<IyourwebpartProps > = React.createElement(
GetandRenderListItems,
{
description: this.properties.description,
// similarly assign values to other props
}
);
ReactDom.render(element, this.domElement);
}
Hopefully this will help.
Edit
you could use array.map() e.g. To render a table using your array you could write something like that.
public render () : React.ReactElement<IyourcomponentsProps> {
return(
<div className={styles.someStyle} >
<table className={styles.container}>
<tr>
<th>ID</th><th>Title</th> <th>Summary</th><th>Created</th
<th>Attachments</th>
</tr>
{ yourArray.map(function(item,key){
let url = this.titleurl(item.ID);
return (<tr className={styles.rowStyle} key={key}> //you can use key if you want to track index
<td></td> <td className={styles.someclass}><a href={url}>{item.Title}</a></td>
</tr> );
})}
</table>
</div>
);
}
I used .bind .map functions to make it happen.
For adding state to the project should be next upate.
I was struggling on handling the arrays and trouble printing
The entire component .tsx file
import * as React from 'react';
import styles from './A.module.scss';
import { IAProps } from './IAProps';
import { escape } from '#microsoft/sp-lodash-subset';
import { PageContext } from "#microsoft/sp-page-context";
import { HttpClient, IHttpClientOptions, HttpClientResponse, SPHttpClient, ISPHttpClientOptions, SPHttpClientResponse } from '#microsoft/sp-http';
import {
Environment,
EnvironmentType
} from '#microsoft/sp-core-library';
export interface ISPLists {
value: ISPList[];
};
export interface Istate {
ID:string;
Title: string;
isLoad?: boolean;
Url:string;
AttachmentFiles:{
Name:string;
Url:string;
ServerRelativeUrl: string;
};
}
export interface ISPList {
ID:string;
Title: string;
Summary : string;
NewsCategory: string;
Created:string;
AttachmentFiles:{
Name:string,
Url:string,
ServerRelativeUrl: string,
};
}
/*
MAIN STARTS HERE
2020-01-28
*/
export default class A extends React.Component<IAProps> {
constructor(props){
super(props);
this.loadNews();
this.getListData=this.getListData.bind(this);
this.geturl=this.geturl.bind(this);
this.loadNews=this.loadNews.bind(this);
}
//variables to render html tags
private ID:any = [];
private Title:any = [];
private Url:any = [];
private data:any =[];
private tro:any=[]; //<tr>
private trc:any=[]; //</tr>
private tdo:any=[]; //<td>
private tdc:any=[]; //</td>
private loadNews(){
this.getListData();
/*
this.getListData().then((response) => {
this.renderList(response.value);
});
*/ // when getlist and redner list are different functions
}
public geturl(query:string){
var path="/Lists/News/DispForm.aspx?ID=";
var currdir=this.props.pagecontext.web.absoluteUrl;
var result=currdir+path+query;
return result;
}
private tags(flag:boolean,first:boolean){
// if first data add <tr>
//if last data add </tr>
//
if (flag && first){
document.getElementById("tro").innerHTML = <tr>;
}else if (flag && !first){
document.getElementById("trc").innerHTML = </tr>;
}
}
private getListData() {
const opt: ISPHttpClientOptions = { headers: { 'Content-Type': 'application/json;odata=verbose' } };
this.props.SPHttpClient.get(this.props.pagecontext.web.absoluteUrl + "/_api/web/lists/getbytitle('News')/items?$select=*,AttachmentFiles&$expand=AttachmentFiles/Title&$orderby=ID desc", SPHttpClient.configurations.v1, opt).then((response: SPHttpClientResponse) => {
response.json().then((json: any) => {
for(let i=0;i<json.value.length;i++){
var url=this.geturl(json.value[i].ID);
if(i==0){ // add tags <tr> </tr>
let flag=true; let first=true;
this.tags(flag,first);
}else if(i==json.value.length){
let flag=false; let first=false;
this.tags(flag,first);
}
this.data.push({ID:<td>{json.value[i].ID}</td>,
Title:<td>{json.value[i].Title}</td>,
Url:<td><img src={json.value[i].AttachmentFiles[0].ServerRelativeUrl} width="300px" height="300px" /></td>
});
// debugger;
this.ID.push(json.value[i].ID);
// this.Title.push(json.value[i].Title);
//this.Url.push(json.value[i].AttachmentFiles[0].absoluteUrl);
this.forceUpdate();
}//close for
});// close response.json
});//close private getListData method
}
// json.value[i].Title}
//json.value[i].AttachmentFiles[0].absoluteUrl}
/*
<td>${json.value[i].Title}</td>
<td></td>
<td>${json.value[i].Created}</td>
<td><img src="${json.AttachmentFiles.ServerRelativeUrl}" width="300px" height="300px" /></td>
*/
public render(): React.ReactElement<IAProps>{
console.log(this.data);
return (
<div className={styles.a} >
<div className={styles.container} ></div>
<span className={ styles.title }>News</span>
<div className={styles.Table}>
<div className={styles.Heading}>
<table >
<tr>
<div className={styles.Cell}>Title</div>
<div className={styles.Cell}>Created</div>
<div className={styles.Cell}>IMGSRC</div>
</tr>
<div className={styles.Cell}>
<span id="tro"></span>
{this.data.map((data)=>
<div> {data.ID}</div>
)
}
</div>
<div className={styles.Cell}>
{this.data.map((data)=>
<div> {data.Title}</div>
)
}
</div>
<div className={styles.Cell}>
{this.data.map((data)=>
<div> {data.Url}</div>
)
}
<span id="trc"></span>
</div>
</table>
</div>
</div>
</div>
);
}
}
In render method .map function as follows
<div className={styles.Cell}>
{this.data.map((data)=>
<div> {data.Url}</div>
)
}
<span id="trc"></span>
</div>
To access data objects within array must declare .bind in the constructor after defining the class.
export default class A extends React.Component<IAProps> {
constructor(props){
super(props);
this.loadNews();
this.getListData=this.getListData.bind(this);
this.geturl=this.geturl.bind(this);
this.loadNews=this.loadNews.bind(this);
}
//variables to render html tags
private data:any =[];
Halfway through.
This is the prototype.
once I am able to extract the data , I can then style the CSS
Thank you for your help.

Unable to fetch the data from spring boot app in React app [duplicate]

This question already has an answer here:
How can I use create-react-app with Spring Boot?
(1 answer)
Closed 3 years ago.
I am working on linking spring boot app and React app but unfortunately while fetching the data from boot app, I am encountering errors as mentioned below.
AppCrypto.js:22 OPTIONS http://localhost:8080/secretdata/allcurrency/ 403
crypto:1 Access to fetch at 'http://localhost:8080/secretdata/allcurrency/' from origin 'http://localhost:3000' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Below are the code snippets.
import React,{Component} from 'react';
import ReactDOM from 'react-dom';
import {Jumbotron,Button,Table} from 'react-bootstrap';
class AppCrypto extends Component{
constructor(props) {
super(props);
this.state = {currencies: null};
}
componentDidMount() {
const requestOptions = {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*' }
};
fetch('http://localhost:8080/secretdata/allcurrency/',requestOptions)
.then(results => {
return results.json();
})
.then(data => {
let currencies =data.results.map((curr) =>{
return(
<Table>
<thead>
<tr>
<th>ID</th>
<th>CURRENCY_NAME</th>
<th>CURRENCY_TICKER</th>
</tr>
</thead>
<tbody>
<tr>
<td>{curr.id}</td>
<td>{curr.currencyname}</td>
<td>{curr.currencyticker}</td>
</tr>
</tbody>
</Table>
)
})
this.setState({currencies:currencies});
console.log("state",this.state.currencies);
})
}
render(){
return(
<div className="container2">
<div className="container1">
{this.state.currencies}
</div>
</div>
);
}
}
export default AppCrypto;
package de.ohmstr.secretdata;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
#RestController
#RequestMapping(path="/secretdata/")
public class SecretDataController {
#Autowired
private SecretDataRepository sdr;
#PostMapping (path="/currency/")
public #ResponseBody String retrievCurrency(#RequestParam String currencyname, #RequestParam String currencyticker){
SecretData sd=new SecretData();
sd.setCurrencyname(currencyname);
sd.setCurrencyticker(currencyticker);
sdr.save(sd);
return "saved";
}
#GetMapping (path="/allcurrency/")
public #ResponseBody Iterable<SecretData> getAllCurrencies(){
return sdr.findAll();
}
#GetMapping (path="/getmessage/")
public #ResponseBody String getMessage(){
return "Welcome to my Secret World";
}
}
You might be getting currencies as undefined, I hope you have made sure you get data but as console throwing error, at some point you might get it undefined.
I am just adding condition to your .then handler as,
let currencies =(data.results || []).map((curr)
=>{ return( <Table> <thead> <tr> <th>ID</th>
<th>CURRENCY_NAME</th>
<th>CURRENCY_TICKER</th> </tr> </thead>
<tbody>
<tr> <td>{curr.id}</td> <td>{curr.currencyname}
</td>
<td>{curr.currencyticker}</td> </tr> </tbody>
</Table> ) })
this.setState({currencies:currencies}, ()=>{
console.log(this.state));

ReactJs - Pass Parameters to Event handler [duplicate]

This question already has answers here:
React 'cannot read property of undefined' when using map
(4 answers)
Closed 5 years ago.
I've just started looking basics of ReactJs. Following is my component to show list of buses. What I want exactly is I want to perform edit/delete operations over buses. But not able to pass busId of corresponding bus to my edit/delete methods.
Following is component code
import React, {Component} from "react";
import { withRouter } from 'react-router-dom'
import {Table,Badge, Label,FormGroup,Container, Row, Col, CardGroup, Card, CardBlock,CardHeader, Button, Input, InputGroup, InputGroupAddon} from "reactstrap";
import {appSettings} from '../../../../Utils/Util.js';
import Pagination from "react-js-pagination";
var axios = require('axios');
class BusList extends React.Component {
constructor(props) {
super(props);
this.state = {
busList:[]
};
this.loadBuses = this.loadBuses.bind(this);
}
componentWillMount() {
this.loadBuses();
}
loadBuses() {
var url = ‘my-api-complete-url-here’;
axios.get(url)
.then((result) => {
var key = 0;
var buses = result.data.map(function(bus,i){
return <tr key={key++}>
<td key={key++}>{bus.id}</td>
<td key={(key++)}>{bus.number}</td>
<td key={(key++)}>
<Button onClick={(e)=>this.editBus(e, bus.id)}>Edit</Button>
<Button onClick={(e)=>this.deleteBus(e, bus.id)}>Delete</Button>
</td>
</tr>
});
this.setState({busList: buses});
})
.catch(function (error) {
console.log(error);
});
}
render() {
return (
<div className="animated fadeIn">
<Table hover responsive striped>
<thead>
<tr>
<th>Sr #</th>
<th>Bus Number</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{this.state.busList}
</tbody>
</Table>
</div>
);
}
editBus(id, e) {
console.log(‘Edit - Bus Id = ' +id);
}
deleteBus(id, e) {
console.log('Delete - Bus Id = ' +id);
}
}
export default BusList;
But when tapped on edit button, I receive this error(
Screenshot)
you're accessing it in wrong order, you're passing (e)=>this.editBus(e, bus.id) and in function you've defined editBus(id, e)
moreover you need to bind(this) at the end of map function
var buses = result.data.map(function(bus,i){
return <tr key={key++}>
<td key={key++}>{bus.id}</td>
<td key={(key++)}>{bus.number}</td>
<td key={(key++)}>
<Button onClick={(e)=>this.editBus(e, bus.id)}>Edit</Button>
<Button onClick={(e)=>this.deleteBus(e, bus.id)}>Delete</Button>
</td>
</tr>
});
Also, you don't need to define key variable. Instead, use second argument i of map function as it is the index of array element.
updated
you need to change your map code with
var buses = result.data.map(function(bus,i){
return <tr key={key++}>
<td key={key++}>{bus.id}</td>
<td key={(key++)}>{bus.number}</td>
<td key={(key++)}>
<Button onClick={(e)=>this.editBus(e, bus.id)}>Edit</Button>
<Button onClick={(e)=>this.deleteBus(e, bus.id)}>Delete</Button>
</td>
</tr>
}.bind(this));
The .bind(this) in the last line does the trick.

ReactJS Redux Live editing

I'm trying to build a similar code like the Widget example from React Redux Universal Hot Example. The only exception is that the data is fetched from PostgreSQL database.
The code lists the groups as it should, but when I click on Edit I get the following errors.
Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method of `AdminGroupList`
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. Check the render method of `AdminGroupList`
Here is my AdminGroupList.js
import React, { Component } from 'react';
import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import { asyncConnect } from 'redux-async-connect';
import { routeActions } from 'react-router-redux';
// import { Table } from 'react-bootstrap/lib';
import * as groupActions from 'redux/modules/groups';
import {isLoaded, load as loadGroups} from 'redux/modules/groups';
import {initializeWithKey} from 'redux-form';
import { GroupForm } from 'components/Admin/GroupForm';
#asyncConnect([{
deferred: true,
promise: ({store: {dispatch, getState}}) => {
if (!isLoaded(getState())) {
return dispatch(loadGroups());
}
}
}])
#connect(
state => ({
groups: state.groups.data,
editing: state.groups.editing,
error: state.groups.error,
loading: state.groups.loading
}),
{ ...groupActions, initializeWithKey, pushState: routeActions.push })
export default class AdminGroupList extends Component {
static propTypes = {
groups: React.PropTypes.object,
pushState: React.PropTypes.func.isRequired,
error: React.PropTypes.string,
loading: React.PropTypes.bool,
initializeWithKey: React.PropTypes.func.isRequired,
editing: React.PropTypes.object.isRequired,
load: React.PropTypes.func.isRequired,
editStart: React.PropTypes.func.isRequired
}
render() {
const groups = Object.values(this.props.groups);
const handleEdit = (group) => {
const {editStart} = this.props;
return () => editStart(String(group.id));
};
const { error, editing, loading, load} = this.props;
let refreshClassName = 'fa fa-refresh';
if (loading) {
refreshClassName += ' fa-spin';
}
return (
<div className="container">
<h1>
Tuoteryhmät ({groups.length})
<button className="btn btn-success" onClick={load}>
{' '} Reload Groups
</button>
</h1>
<Helmet title="Groups"/>
{error &&
<div className="alert alert-danger" role="alert">
<span className="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
{' '}
{error}
</div>}
{groups && groups.length &&
<table className="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th></th>
</tr>
</thead>
<tbody>
{
groups.map((group) => editing[group.id] ?
<GroupForm formKey={String(group.id)} key={String(group.id)} initialValues={group}/> :
<tr key={group.id}>
<td>{group.id}</td>
<td>{group.name}</td>
<td>
<button className="btn btn-primary" onClick={handleEdit(group)}>
<i className="fa fa-pencil"/> Edit
</button>
</td>
</tr>)
}
</tbody>
</table>}
</div>
);
}
}
And here is GroupForm.js
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {reduxForm} from 'redux-form';
import groupValidation from 'utils/GroupValidation';
import * as groupActions from 'redux/modules/groups';
#connect(
state => ({
saveError: state.groups.saveError
}),
dispatch => bindActionCreators(groupActions, dispatch)
)
#reduxForm({
form: 'group',
fields: ['id', 'name'],
validate: groupValidation
})
export default class GroupForm extends Component {
static propTypes = {
fields: PropTypes.object.isRequired,
editStop: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
invalid: PropTypes.bool.isRequired,
pristine: PropTypes.bool.isRequired,
save: PropTypes.func.isRequired,
submitting: PropTypes.bool.isRequired,
saveError: PropTypes.object,
formKey: PropTypes.string.isRequired,
values: PropTypes.object.isRequired
};
render() {
const { editStop, fields: {id, name}, formKey, handleSubmit, invalid,
pristine, save, submitting, saveError: { [formKey]: saveError }, values } = this.props;
return (
<tr>
<td>{id.value}</td>
<td>
<input type="text" className="form-control" {...name}/>
{name.error && name.touched && <div className="text-danger">{name.error}</div>}
</td>
<td>
<button className="btn btn-default"
onClick={() => editStop(formKey)}
disabled={submitting}>
<i className="fa fa-ban"/> Cancel
</button>
<button className="btn btn-success"
onClick={handleSubmit(() => save(values)
.then(result => {
if (result && typeof result.error === 'object') {
return Promise.reject(result.error);
}
})
)}
disabled={pristine || invalid || submitting}>
<i className={'fa ' + (submitting ? 'fa-cog fa-spin' : 'fa-cloud')}/> Tallenna
</button>
{saveError && <div className="text-danger">{saveError}</div>}
</td>
</tr>
);
}
}
This error message means you have an issue with your imports.
If you export export GroupForm by default with default class GroupForm, you should import it without the curly brackets in AdminGroupList.js:
Replace this line import { GroupForm } from 'components/Admin/GroupForm' by import GroupForm from 'components/Admin/GroupForm'

Categories