React output JSON on new line - json

I am have managed to output the JSON from an API, however it is outputted in one large block, I however wish to display each piece of json on a new line everytime there is a closing '}'.
import React, { Component } from 'react';
import './App.css';
import $ from 'jquery';
class App extends Component {
state = {result : null}
componentDidMount = () => {
$.ajax({
type: "GET",
url: 'http://localhost:3001/data',
data: {},
xhrFields: {
withCredentials: false
},
crossDomain: true,
dataType: 'JSON',
success: (result) => {
this.setState({result : result});
}
});
};
render() {
return (
<div className="App">
<header>
<h2>Last Application Deployment </h2>
</header>
<div id='renderhere'>
{JSON.stringify(this.state.result)}
</div>
</div>
);
}
}
export default App;

try to wrap your text around this css style. and your issue will be solved. No complicated functions needed for this.
<p style={{whiteSpace: 'pre-line'}}>my json text goes here \n\n</p>

First option: if you want to output JSON for debugging purpose, you should try react-json-pretty
Second option: if what you trying to do is supposed to be for production do something like this:
<div id='renderhere'>
<pre>{JSON.stringify(this.state.result, null, 2)}</pre>
</div>

Related

Import external component and loose reactivity in vue3

I have 2 projects/folders (with Lerna on the root).
The first one is uicomponents with some components and the second one is testing a simple app which uses some component from uicomponents.
I created a simple counter component (Counter.vue) :
<template>
<div>
<h3>Total clicks: {{ count }}</h3>
<div class="button-container">
<button class="inc" #click.prevent="increment">Add</button>
<button class="dec" #click.prevent="decrement">Subtract</button>
</div>
</div>
</template>
<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'Counter',
props: {
startingNumber: {
type: Number,
required: false,
default: 0,
},
},
setup(props) {
const count = ref(props.startingNumber);
const increment = () => {
count.value += 1;
alert(count.value);
};
const decrement = () => {
count.value -= 1;
};
return {
count,
increment,
decrement,
};
},
});
</script>
And I import it in my app on a simple page :
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<counter :starting-number="5"></counter>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import Counter from '#uicomponents/counter';
export default defineComponent({
name: 'HelloWorld',
components: {
Counter,
},
props: {
msg: {
type: String,
required: false,
default: 'Me',
},
},
});
</script>
Lerna correctly replace all my components path and I retrieve my components Counter in my pages with all HTML. Buttons works well and my alert are displays with the correct value BUT my html are not refreshed.
This text <h3>Total clicks: {{ count }}</h3> stay "Total clicks: 0". My "count" ref is well updated because the alert displayed it correct but not in html.
I have a similar problem with lost reactivity. My setup is a bit different, but in the end it's the same result.
I'm trying to build a small plugin system which loads external components
Roughly I try to do this
// pluginSystem.js is accessible through window.myps
// ...
init(app) {
vueApp = app;
},
// ...
loadPlugin(data) {
vueApp.component(data.component.name, data.component);
}
And my external component looks like this
// main.js
import Counter from './components/Counter.vue';
window.myps.loadPlugin({
component: Counter,
});
Button click in counter, etc. works, console logging is fine as well, but component data is not updated.
I also tried defineComponent and defineAsyncComponent, but as you I had no luck with it...
Try it
import { defineAsyncComponent, defineComponent } from "vue"
components: {
Counter:defineAsyncComponent(() => import("#uicomponents/counter"))
}

How to access values of JSON object which is bound to State of component in ReactJS

I am getting JSON data from WebService and I am initializing it to the state.
In UI, I want to directly bind a value to the textbox value field.
Here i was able to log the value of prod
But while binding the value to textbox I get error "Unable to get property of undefined or null reference":
import * as React from 'react';
import * as $ from "jquery";
interface IBudgetRequestReadOnly {
data: [any];
}
export class BudgetRequestReadOnly extends React.Component<{ RequestNumber }, IBudgetRequestReadOnly> {
constructor(props) {
super(props);
this.state = {
data: [{}],
};
}
componentDidMount() {
const RequestNumber = this.props.RequestNumber;
$.ajax({
type: "POST",
url: "Home/GetRequestByRequestID",
dataType: "json",
data: { requestID: RequestNumber },
success: function (msg) {
if (msg) {
this.setState({ data: msg });
console.log(this.state.data["product"].product);
}
}.bind(this),
error: function (msg) {
}
});
}
public render() {
return <div>
<div className="col-sm-12 Card ">
<div className="row"> </div>
<div className="row">
<div className="col-sm-12">
<label>Product Need<sup>*</sup></label>
<input type="text" className="form-control" aria-describedby="basic-addon1"
value={this.state.data["product"]} disabled />
</div>
</div>
<br />
</div>
</div >;
}
}
That's because your ajax request is asynchronous. Currently this is happening:
Your constructor is called.
render() is called
componentDidMount is called
The thing is that the render function you're trying to bind this.state.data.product.product but this doesn't exist (yet) on your first mount. Therefore trowing the error Unable to get property of undefined or null reference because this.state.data.product doesn't exist in this.state.data.
You could set a default value within your component state:
constructor(props) {
super(props);
this.state = {
data: {
product: {
product: '',
}
},
};
}
This will have this.state.data.product.product as an empty string by default, and upon obtaining your data from the API and updating the state, the actual data.product.product is set.
Now you can use <input value={this.state.data.product.product} /> without getting an error.

Issue in accessing API/json with multiple sections

I'm trying to display all sections of the following json file into my reactjs page: https://api.myjson.com/bins/cdres
below is the code:
import React, { Component } from 'react';
import {render} from "react-dom";
class apps extends Component {
state = {
data: {
segments: [],
totals: [],
}
}
componentWillMount(){
fetch('https://api.myjson.com/file', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-type': 'application/json',
'Authorization': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiR3JlZyIsInVuaXF1ZV9uYW1lIjoiZ2dyYWZmIiwibmJmIjoxNTI0ODM5Nzc1LCJleHAiOjE1MjQ5MjYxNzV9.xhvdfaWkLVZ_HLwYQuPet_2vlxNF7AoYgX-XRufiOj0'
},
}
) /*end fetch */
.then(results => results.json())
.then(data => this.setState({ data: data }))
}
render() {
console.log(this.state.data);
return (
<div className="clientContainer">
{
this.state.data.segments.map( item =>(
<div>
<span> {item.clientName} </span>
</div>
))
}
{
this.state.data.totals.map(item =>(
<div>
<span> {item.segmentType} </span>
<span> {item.adjTotalSqrFt} </span>
</div>
))
}
</div>
);
}
}
export default app;
...the code works for consuming data from the segments and totals section of the json file, but am having trouble getting the id and username from the top section?
data is an object rather than an array so calling map on it triggers an error.
Simply do this.state.data.segments.map(...) instead, and change your initial state to
state = { data: { segments: [] } }
map is a function of array. The data is an object while data.segments is an array. You will need to change the code as below
<div className="clientContainer">
{
this.state.data.segments.map( item =>( //change here
<div>
<span> {item.clientName} </span>
</div>
))
}
</div>

REACT - fetch json data from url and display it

I am new to REACT and I was trying to learn how to get and display a specific parameter from a json style message stored in an url.
For instance, the video I was trying to show, is stored in and url, which is a field of the json message itself, so it would look like this:
{
"type": "video",
"url": "http://somewebsite.com/wantedvideo.mp4"
}
From what i've read, fetch() is one way to get the data, but unfortunately I couldn't seem to understand what can be missing in the code I tried:
Here's my newbie attempt:
import React, {Component} from 'react';
class App extends Component{
constructor()
{
super();
this.state={
data: [],
}
}
componentDidMount()
{
fetch('https://demo7443497.mockable.io/stream/video')
.then((response) => response.json())
.then((findresponse)=>{
console.log(findresponse.url)
this.setState({
data:findresponse.url,
})
})
}
render()
{
return(
<div>
{this.state.data.url}
</div>
)
}
}
export default App;
My render() always looked suspiciously too simple for me, so my apologies for any "mad" mistakes I may have made
PS: If instead of a video there was some other data format such as an image or plain text in the url of the url field, is there an disavantadge in using the same code to fech it?
Thank you
this.setState({
data: findresponse.url,
})
You are setting url value to data and
in render accessing the data.url. (url on data which does not exists).
If you just put {this.state.data},you will get url value.
Also, if you are getting Object from response then declare state as
this.state = {
data: {}, //instead []
}
EDIT :
e.g. to display video using video control as per comment.
<video width="400" controls>
<source src={this.state.data} type="video/mp4" />
Your browser does not support HTML5 video.
</video>
Working codesandbox
I'm going to provide a simple App component which look like this -
import React, {Component} from 'react';
import { Player } from 'video-react';
class App extends Component{
constructor() {
super();
this.state = {
data: []
}
}
componentDidMount() {
fetch('https://demo7443497.mockable.io/stream/video')
.then( resp => resp.json())
.then((data)=> {
this.setState({
data: data.url
})
})
}
render() {
return(
<Player
playsInline
src={ this.state.data }
/>
)
}
}
export default App;
Import css -
import "node_modules/video-react/dist/video-react.css"; // import css
#import "~video-react/styles/scss/video-react"; // or import scss
Add <link rel="stylesheet" href="/css/video-react.css" /> inside index.html
Try this it will work for all browsers.

React output JSON from API

I have managed to get JSON from my api I have created, however I am having trouble actually rendering that JSON. I have managed to output it in the console by 'stringify'-ing it, however I cannot seem to actually render JSON to the page.
import React, { Component } from 'react';
import './App.css';
import $ from 'jquery';
function getData() {
return $.ajax({
type: "GET",
url: 'http://localhost:3001/data',
data: {},
xhrFields: {
withCredentials: false
},
crossDomain: true,
dataType: 'json',
success: handleData
});
}
function handleData(data /* , textStatus, jqXHR */ ) {
console.log(JSON.stringify(data));
return JSON.stringify(data);
}
class App extends Component {
render() {
return (
<div className="App">
<header>
<h2>Last Application Deployment </h2>
</header>
<div id='renderhere'>
{JSON.stringify(getData().done(handleData))}
</div>
</div>
);
}
}
export default App;
you cant execute a function in render method in return.you can use react lifecycles and store result in state like this =>
class App extends Component {
state = {result : null}
componentDidMount = ()=>{
$.ajax({
type: "GET",
url: 'http://localhost:3001/data',
data: {},
xhrFields: {
withCredentials: false
},
crossDomain: true,
dataType: 'json',
success: (result)=>{
this.setState({result : result});
}
});
};
render() {
return (
<div className="App">
<header>
<h2>Last Application Deployment </h2>
</header>
<div id='renderhere'>
{this.state.result && and what you want because i dont know why you want use JSON.stringfy - you use .map() or ...}
</div>
</div>
);
}
}
I suggest you see this article and this.
I've made a demo of how you can solve this: http://codepen.io/PiotrBerebecki/pen/amLxAw. The AJAX request should not be made in the render method but in a componentDidMount() lifecycle method. Also, it's best to store the response in state. Please see the guidance in the React docs: https://facebook.github.io/react/tips/initial-ajax.html
Fetch data in componentDidMount. When the response arrives, store the data in state, triggering a render to update your UI.
Here is the full code:
class App extends React.Component {
constructor() {
super();
this.state = {
time: '',
string: ''
};
}
componentDidMount() {
$.ajax({
type: "GET",
url: 'http://date.jsontest.com/'
})
.then(response => {
this.setState({
time: response.time,
string: JSON.stringify(response)
});
})
}
render() {
return (
<div className="App">
<header>
<h2>Last Application Deployment </h2>
</header>
<div id='renderhere'>
Time: {this.state.time} <br /><br />
String: {this.state.string}
</div>
</div>
);
}
}
ReactDOM.render(
<App />, document.getElementById('content')
);