React JS Accessing JSON as State - json

I'm completely brand new to React JS and am trying to create an application that will grab JSON data from a pokemon API, which I will then use to display on screen. Right now, I have it set up so that the user has to input the name of the pokemon they are looking for, i.e. pikachu, and when the search button is pressed, the application will make the API call to return the JSON. I've been searching for the past few days, and cannot seem to find anything to work with the way I currently have my code set up. How do I bind the JSON output to a component that I would then be able to display to the user?
Here's the js code (App.js)
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import ReactDOM from 'react-dom';
class App extends Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Text field value is: ' + this.state.value);
fetch('https://pokeapi.co/api/v2/pokemon/'+this.state.value+'/')
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data.name +" "+ data.id);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
}
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<input type="text"
placeholder="enter name of pokemon here"
value={this.state.value}
onChange={this.handleChange}
/>
<button type="button" onClick={this.handleSubmit}>Search the Pokedex</button>
</div>
);
}
}
export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tag above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start`.
To create a production bundle, use `npm run build`.
-->
</body>
</html>
Screenshot of issue:
http://imgur.com/a/g9H5r

Try this
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import ReactDOM from 'react-dom';
class App extends Component {
constructor(props) {
super(props);
this.state = {
value: '',
data: {} //filled by fetch data from API
};
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Text field value is: ' + this.state.value);
var _this = this;
fetch('https://pokeapi.co/api/v2/pokemon/'+this.state.value+'/')
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data.name +" "+ data.id);
_this.setState({data: data});
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
_this.setState({data: {}});
});
}
render() {
var data = this.state.data;
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<input type="text"
placeholder="enter name of pokemon here"
value={this.state.value}
onChange={this.handleChange.bind(this)}
/>
<button type="button" onClick={this.handleSubmit.bind(this)}>Search the Pokedex</button>
<h3>{data.id}</h3>
<h3>{data.name}</h3>
</div>
);
}
}
ReactDOM.render(App, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tag above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start`.
To create a production bundle, use `npm run build`.
-->
</body>
</html>

Related

window.MathJax is undefined?

Hi i Have a problem with MathJax library. I want to display the mathjax formula on the screen, but when I use window.MathJax I get the error that it is undefined. Here is how I installed the MathJax in my html file:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Test</title>
<link rel="icon" href="/icons/favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="/icons/favicon.ico" type="image/x-icon">
<!-- inject:css -->
<!-- endinject -->
<script type="text/x-mathjax-config">
MathJax = {
options: {
renderActions: {
addMenu: []
}
},
};
MathJax.Hub.Config({
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
processEscapes: true
}
});
</script>
<script async type="text/javascript" src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-mml-svg.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
</head>
<body>
<div id="application-content">
</div>
</body>
<!-- inject:js -->
<!-- endinject -->
<script type="application/javascript">
EMBED.default.init();
</script>
</html>
And here is the component where I use the library:
import React, { Component } from 'react';
export default class MathBlock extends Component {
constructor(props) {
super(props);
this.state = {
open: false,
};
}
render() {
const text = this.props.block.getText();
const latexRegex = /\${2}(.*?)\${2}/;
const hasLatex = latexRegex.test(this.props.block.getText());
return (
<div>
<div
dangerouslySetInnerHTML={{
__html: hasLatex
? window.MathJax.tex2svg(text.replaceAll('$', '')).innerHTML
: window.MathJax.mathml2svg(text).innerHTML,
}}
/>
</div>
);
}
}
MathBlock.propTypes = {
block: React.PropTypes.object.isRequired,
};
Does anyone know what is the problem here?
Because the script tag that loads MathJax has the async attribute, it may not be loaded when your EMBED.default.init(); command likely will run before MathJax is loaded, and so before window.MathJax has been defined.
You could either remove the async attribute (which will mean your page will have to wait for MathJax to load and compile before the rest of the page is processed, slowing down your initial view of the page), or you could put the EMBED.default.init(); in MathJax's startup ready() function so that it is not performed until MathJax is loaded.
You are loading MathJax version 3, but your current configuration seems to be a mix of v2 and v3 configurations, and it is currently being ignored entirely by MathJax.
You could use
<script>
MathJax = {
options: {
renderActions: {
addMenu: []
}
},
tex: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
processEscapes: true
},
startup: {
ready() {
MathJax.startup.defaultReady();
EMBED.default.init();
}
}
};
</script>
(a correct v3 configuration) in place of your current configuration script, and see if that avoids the problem.

Can't render button from React in html

I have a ready-made site where I need to import a button from react:
<html>
<head>
</head>
<body>
<div id="root"></div>
<script>
ReactDOM.createRoot(<App />, document.getElementById("root"));
</script>
<script src="https://unpkg.com/react#18/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#18/umd/react-dom.production.min.js" crossorigin></script>
<!-- Load our React component. -->
<script src="src/App.js"></script>
</body>
</html>
From here:
import './App.css';
import { ConnectButton } from '#rainbow-me/rainbowkit';
function App() {
return (
<div className="App">
<header className="App-header">
<ConnectButton/>
</header>
</div>
);
}
export default App;
index.js +I have already changed the render values ​​to createRoot as well as other related values ​​from Nikki9696 comment.
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import '#rainbow-me/rainbowkit/styles.css';
import {
getDefaultWallets,
RainbowKitProvider,
} from '#rainbow-me/rainbowkit';
import { configureChains, createClient, WagmiConfig } from 'wagmi';
import { mainnet, polygon, optimism, arbitrum } from 'wagmi/chains';
import { alchemyProvider } from 'wagmi/providers/alchemy';
import { publicProvider } from 'wagmi/providers/public';
const { chains, provider } = configureChains(
[mainnet, polygon, optimism, arbitrum],
[
alchemyProvider({ apiKey: process.env.ALCHEMY_ID }),
publicProvider()
]
);
const { connectors } = getDefaultWallets({
appName: 'Evefund',
chains
});
const wagmiClient = createClient({
autoConnect: true,
connectors,
provider
})
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<WagmiConfig client={wagmiClient}>
<RainbowKitProvider chains={chains}>
<App />
</RainbowKitProvider>
</WagmiConfig>
</StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more:
reportWebVitals();
But its not rendering, what Im doing wrong? (html just a sample)
Thanks.
p.s. ChatGPT says everything should work C:
you need to transpile your jsx into javascript using some tool like babel:
<html>
<head>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
ReactDOM.render(<App />, document.getElementById("root"));
</script>
<script src="https://unpkg.com/react#18/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#18/umd/react-dom.production.min.js" crossorigin></script>
<script src="https://unpkg.com/#babel/standalone#7.8.3/babel.js"></script>
<!-- Load our React component. -->
<script src="src/App.js" type="text/babel"></script>
</body>
</html>
because javascript doesnt understand jsx it only understands functions from react like React.createElement()

Open Graph not displaying properly on Twitter [duplicate]

I am trying to fetch content from an API and show it in a page. It's working fine but when I am trying to view page source code it's not showing those content that I am getting from API. I am using Next.js for this project and the code that I have used is following. Is there anyone who can help help me to solve this issue?
import React, { Fragment, useEffect, useState } from 'react'
import { API_BASE_URL } from '../Config/Settings'
import SideBar from '../Layouts/SideBar'
import Link from "next/link"
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import axios from 'axios'
export const CmsPage = (props) => {
const [PageHtmlContent, setPageContent] = useState('');
const [PageTitle, setPageTitle] = useState('');
const [PageDescription, setPageDescription] = useState('');
const [SeoKeyword,setSeoKeyword]=useState('');
useEffect( async() => {
let body = {pageTypeCode:props.pageType,pageName:props.pageName};
const config = {
headers: {
'x-auth-token':"rpsite-public-token"
}
}
try {
const res= await axios.post(API_BASE_URL+'/api/cms/page',body,config);
// alert(res.data.content);
setPageContent(res.data.content);
setPageTitle(res.data.seoTitle);
setPageDescription(res.data.seoDescription);
setSeoKeyword(res.data.seoKeyword);
}
catch(err) {
setPageContent('<b>Something went wrong!</b>');
}
},[props]);
return (
<section class="inner-body-section">
<Head>
<title>{PageTitle}</title>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<meta name="keywords" content={SeoKeyword} />
<meta name="description" content={PageDescription}/>
</Head>
<div class="container">
<div class="row">
<div class="col-md-3">
<SideBar/>
</div>
<div class="col-md-9">
<div className="inner-body-content">
<div id="contentBlock" className="page-content" dangerouslySetInnerHTML={{__html:PageHtmlContent}}></div>
</div>
</div>
</div>
</div>
</section>
)
}
export default CmsPage;
What you get when looking at View Page Source is the HTML returned by the server.
Because you're making the request and populating the data inside a useEffect this will only occur on the client, thus the data won't be visible in the page's source.
If you want the data to be populated on the server you may want to have a look at getStaticProps or getServerSideProps instead.
Here's an example of how you can use getStaticProps to populate the data on the server-side (a similar approach could be used with getServerSideProps).
export async function getStaticProps(context) {
const res = await axios.post(`${API_BASE_URL}/api/cms/page`);
// Assuming `res.data` format: { content, seoTitle, seoDescription, seoKeyword }
return {
props: res.data
};
}
const CmsPage = ({ content, seoTitle, seoDescription, seoKeyword }) => {
return (
<>
<Head>
<title>{seoTitle}</title>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<meta name="keywords" content={seoKeyword} />
<meta name="description" content={seoDescription}/>
</Head>
<section class="inner-body-section">
<div class="container">
<div class="row">
<div class="col-md-3">
<SideBar/>
</div>
<div class="col-md-9">
<div className="inner-body-content">
<div id="contentBlock" className="page-content" dangerouslySetInnerHTML={{__html: content}}></div>
</div>
</div>
</div>
</div>
</section>
</>
)
}
export default CmsPage;

oauth2 callback displays referenced stylesheet css file literally

I have a spring boot application that uses a GitHub oauth2 app for authentication.
When the successful authentication returns then one of the stylesheet files will be displayed. Literally. It is a random choice as to which one it is. The browser is firefox. The url will be http://machine:8090/css/demo.css. Resending http://machine:8090 will then display the screen properly.
Commenting out the css lines in the html will display the expected result after a return from github. But obviously I lose any formatting.
<!DOCTYPE html>
<html>
<head>
<title>Bikes Application</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width"/>
<script src="https://unpkg.com/vue#2.6.8/dist/vue.js"></script>
<script src="https://unpkg.com/vuex#3.1.0/dist/vuex.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios#0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash#4.13.1/lodash.min.js"></script>
<!-- <link rel="stylesheet" type="text/css" href="css/demo.css"/>
<link rel="stylesheet" type="text/css" href="/webjars/bootstrap/css/bootstrap.min.css"/> -->
</head>
<body>
<div id="app-3" class="container">
<template v-if="!authd">
Click here to Github Login
</template>
<template v-else>
Logged in as: <span id="user">{{ user }}</span>
<div>
<button v-on:click="logout" class="btn btn-primary">Logout</button>
</div>
<p>Get your greeting here</p>
<p>Listing Owners and their bikes with Thymeleaf here</p>
<p>Listing Owners and their bikes with vue in a thymeleaf template here</p>
</template>
</div>
<script type="application/javascript" src="authorisation.js"></script>
</body>
</html>
Does anyone know what is happening here?
Update from comments.
I don't think it is connected to grant types because if, before authentication, I go to machine:8090/greeting for instance then I am redirected to GitHub, authenticate and then passed to greeting (which does contain a subset of the css files listed in index.html). And that works; the contents of css is not listed.
The oauth app in GitHub has a redirect url of machine:8090/login. I have tried machine:8090/ and get the same result - after authentication, I see a css file listed.
Here is WebSecurityConfiguration.java
#Configuration
//#EnableEurekaClient
#EnableOAuth2Sso
#PropertySources(
{
#PropertySource("classpath:application-github.properties")
}
)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
// .csrf()
// .disable()
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**", "/unpkg.com/**", "/cdn.jsdelivr.net","/error**","/*.js","/*.css")
.permitAll()
.anyRequest()
.authenticated()
.and()
.logout()
.logoutSuccessUrl("/")
.permitAll()
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
I have expanded index.html. Are there other files that would be helpful?
and here is the javascript
vm = new Vue({
el: '#app-3',
data: function() {
return {
user: null,
baseurl: "http://mint191:9080/",
authd: false
}
},
methods: {
logout: function () {
axios({
method: 'post',
url: 'logout',
baseURL: this.baseurl
})
.then(response => {
console.log(`post logout: ${JSON.stringify(response)}`)
this.user = null
this.authd = !this.authd
console.log(`logout: authorised is ${this.authd}`)
console.log(`logout: user is ${this.user}`)
})
.catch(function (error) {
console.log("logout has gone wrong" + error)
})
}
},
mounted () {
axios({
method: 'get',
url: 'user',
baseURL: this.baseurl
})
.then(response => {
console.log(`get user: ${JSON.stringify(response)}`)
this.user = response.data.userAuthentication.details.login
this.authd = !this.authd
console.log(`authorised is ${this.authd}`)
})
.catch(function (error) {
console.log("nothing in user" + error)
})
}
})

Ng-view or ui-view not displaying html page

I am relatively new to Angularjs, and am building a website. When I try to inject todo.html into the body tags of index.html nothing happens. I am not getting any errors in the console. I have read many of the similar posts to mine, and have already tried
Remove the ng-include from the body of index.html
Moved the links for angualrjs and bootstrap from the body of index.html to the head
Originally I used Ng-route but it did not work, so I implemented ui-router
I have tried both ng-route and ui-router,and both run without any errors. I don't think it has anything to do with either.
index.html
<html ng-app="todoApp">
<head>
<!-- META -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Optimize mobile viewport -->
<title>Todo App</title>
<!-- Angular ans JS links-->
<script src="vendor/angular/angular.min.js"></script>
<script src="vendor/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="app/app.js"></script>
<script src="app/services/todo.service.js"></script>
<script src="app/controllers/todo.controller.js"></script>
<!-- <script src="vendor/angular-route/angular-route.min.js"></script>-->
<!--Jquery and Bootstrap Links-->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://npmcdn.com/tether#1.2.4/dist/js/tether.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/js/bootstrap.min.js" integrity="sha384-VjEeINv9OSwtWFLAtmc4JCtEJXXBub00gtSnszmspDLCtC0I4z4nqz7rEFbIZLLU"
crossorigin="anonymous"></script>
<!-- css links -->
<link href="vendor/bootstrap-css-only/css/bootstrap.min.css" rel="stylesheet"><!-- load bootstrap -->
<link rel="stylesheet" href="assets/css/todoApp.css">
<link rel="stylesheet" type="text/css" href="assets/css/Header-Picture.css">
</head>
<body >
<div ng-include="'app/views/header.html'"></div>
<!--<div ng-include="'app/views/footer.view.html'"></div>
-->
<ui-view></ui-view>
<!--<div ui-view></div>-->
</body>
</html>
App.js
var todoApp = angular.module('todoApp', [
'ui.router'
]);
todoApp.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('todo', {
url: "/",
templateUrl: 'views/todo.html',
controller: 'TodoController'
})});
todo.controller.js
todoApp.controller('TodoController', ['$scope', 'Todos', function TodoController($scope, Todos) {
$scope.formData = {};
console.log("in the TodoController");
// when landing on the page, get all todos and show them
Todos.get()
.success(function(data) {
$scope.todos = data;
});
// when submitting the add form, send the text to the spring API
$scope.createTodo = function() {
if(!$scope.todoForm.$valid) {
return;
}
Todos.create($scope.formData)
.success(function(data) {
$scope.formData = {}; // clear the form so our user is ready to enter another
$scope.todos.push(data);
});
};
// delete a todo after checking it
$scope.deleteTodo = function(id) {
Todos.delete(id)
.success(function(data) {
angular.forEach($scope.todos, function(todo, index){
if(todo.id == id) {
$scope.todos.splice(index, 1);
}
});
});
};
// when submitting the add form, send the text to the node API
$scope.saveTodo = function(todo) {
Todos.update(todo)
.success(function(data) {
$scope.editedTodo = {};
});
};
$scope.editedTodo = {};
$scope.editTodo = function(todo) {
$scope.editedTodo = todo;
}
$scope.revertTodo = function() {
$scope.editedTodo = {};
}
}]);
You should be using otherwise to force the first state to be loaded as below
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('todo', {
url: "/",
templateUrl: 'todo.html',
})
$urlRouterProvider.otherwise('/');
});
Your index.html will look like
<div ng-include="'app/views/header.html'"></div>
<ui-view>
</ui-view>
LIVE DEMO
I added the code posted by #Aravind to my project which I belive was an improvement on my own and was correct. But the issue was the file path to the todo.html. The file path in the original was views/todo.html
the correct path is app/views/todo.html
My original code:
todoApp.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('todo', {
url: "/",
templateUrl: 'views/todo.html',
controller: 'TodoController'
})});
Current Working Code
todoApp.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('todo', {
url: "/",
templateUrl: 'app/views/todo.html',
})
$urlRouterProvider.otherwise('/');
});