React call stateless component - javascript

So i am trying to get some data from the backend just before my home component renders:
This is the home component:
class App extends Component {
constructor(props) {
super(props);
//asta e o alternativa la componentwillmount dar nu pot sa alterez
//starea in constructor cica
}
componentWillMount(){
console.log('componentWillMount is executing')
console.log(store.getState())
//GetInitialData.bind(this)()
GetInitialData();
console.log('component should have executed')
}
This is my stateless component responsible for making the request and dispatching the response to the redux store:
import axios from 'axios';
import { get_library } from '../../Redux/actions/Actions'
import store from "../../Redux/store/Store";
import { connect } from "react-redux";
const mapDispatchToProps = dispatch => {
return {
get_library : context => dispatch(get_library(context))
}
}
const GetInitialData2 = () => {
console.log('This should work')
}
const GetInitialData = (props) => {
console.log('Making the GET request')
//axios.get('http://localhost:8080/try')
axios({
method : 'get',
url : 'http://localhost:8080/getLibrary',
headers : {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization' : 'Bearer ' + getToken(),
},
})
.then(response => {
console.log('Store in Initial Data')
console.log(store.getState())
//store.dispatch(get_library(response.data))
//this.props.store.dispatch(get_library(response.data))
props.get_library(response.data)
//this.setState({ data: response.data });
console.log('New state now')
//console.log(this.state)
})
};
function getToken() {
// Retrieves the user token from localStorage
return localStorage.getItem('id_token')
}
//function GetInitialData (){ connect(null, mapDispatchToProps)(Connected_GetInitialData)}
//export default GetInitialData;
export default connect(null, mapDispatchToProps)(GetInitialData)
export default GetInitialData2;
My problem is that i keep getting props is not defined error which is pointing to the home component, no matter what. Even if i call GetInitialData2(which only prints something) or GetInitialData.
There is something i'm not understanding. I don't need to pass anything to my GetInitialData function since all it does is alter the redux store.
EDIT - With middleware:
class App extends Component {
componentDidMount() {
console.log('In DidMount, calling function');
GetInitialData();
console.log('DidMount should have executed');
}
And:
const GetInitialData = () => {
console.log('Making the GET request')
//axios.get('http://localhost:8080/try')
axios({
method : 'get',
url : 'http://localhost:8080/getLibrary',
headers : {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization' : 'Bearer ' + getToken(),
},
})
.then(response => {
console.log('Store in Initial Data')
console.log(store.getState())
console.log(response.data)
//store.dispatch(get_library(response.data))
store.dispatch(get_library(response.data))
//this.setState({ data: response.data });
console.log('New store state now')
console.log(store.getState())
})
};
function getToken() {
// Retrieves the user token from localStorage
return localStorage.getItem('id_token')
}
export default GetInitialData;
The result is that it just stops at store.dispatch and does nothing. All the console.logs work and i get a valid response.
Result... after too many hours: Seems that it was failing silently at
reducer level where i had:
const initialState = {
library: {},
playlist_names: [],
playlists : [],
songs : [],
articles : [],
};
And instead it should have been : library : [];, the error was: TypeError: Invalid attempt to spread non-iterable instance. I only got to this by printing the response.data in the console and manually running store.dispatch from browser console... I still do not understand why that error didn't surface.

Related

next.js is not returning items on getStaticProps()

I am trying to load items to my next.js page and it will fail:
import {getadminInfo} from '../../dataFetch/adminInfo'
import {addItem} from '../../dataFetch/catalog'
import {useState} from "react"
import { getList } from '../../dataFetch/catalogList'
export async function getStaticProps() {
const adminData = await getadminInfo()
const catlist = await getList()
return {
props: {
catlist,
adminData
}
}
}
export default function Main({allPostsData, adminData, catlist}) {
}
My function is :
export function getList() {
const pageInfo = {
page_size : "10",
page:"1"
}
const url = "http://localhost:8000/api/catalog/list?page_size="+pageInfo.page_size+"&page="+pageInfo.page;
try {
fetch(url, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
fData=JSON.parse(JSON.stringify(data.response))
console.log("Returned catalog")
return fData
})
.catch(error => console.log(error))
} catch (err) {
console.log(err)
}
}
The API works and I get the right info back but I cannot load it to the page:
Error: Error serializing .catlist returned from getStaticProps in "/admin/main".
Reason: undefined cannot be serialized as JSON. Please use null or omit this value.
I found the issue. I did not implement the fetch correctly. It should have been async.
The reason I did not get the info is because nothing was returned.

Response from API returns data, state is undefined - React.JS

I have a REACT component:
import React from 'react';
import Weather from '../service/weatherAPI.js';
export default class DisplayWeather extends React.Component {
constructor(props){
super(props);
this.state = {
weatherData: []
}
this.getWeatherData = this.getWeatherData.bind(this);
}
componentDidMount(){
this.getWeatherData();
}
async getWeatherData(){
let data = await Weather(this.props.location)
this.setState({ weatherData: data});
console.log(this.state.weatherData)
}
This function references a function exported from another file which is using fetch to call an endpoint. All the data returns correctly from the endpoint I am calling. However, when trying to set this data onto the state, my data is undefined.
Below is my API call, just in case I have missed anything here:
const Weather = (location) => {
fetch(url, {
Method: 'GET',
headers : {
'Accept': 'application/json'
},
})
.then((raw) => raw.json())
.then((response) => {
return response
})
}
export default Weather;
Thanks in advance.
You need to return the promise like this in your weather function:
const Weather = (location) => {
return fetch(url, {
Method: 'GET',
headers : {
'Accept': 'application/json'
},
})
.then((raw) => raw.json())
.then((response) => {
return response
})
}
That way the await is working on the promise instead of just the function.

How can I run a code after another has already ended running?

In less than 1 second, I have to post something into a JSON file and then get that exact data updated. When running the code, it seems that I post the data in the JSON file but when I try to get it, it gets the old data, not the updated one.
How can i run get method after post method has ended running?
I ran this post method
import Game from "./components/Game/Game";
class App extends React.Component {
postUserInfo(){
fetch("http://localhost:8080/api/users" , {
method: "post" ,
mode: "cors",
headers: {
"Content-type": "application/json",
},
body:JSON.stringify({username:this.state.userInput, bestscore:0})
})
.then((res) => res.json())
.then((data => {console.log(data)}))
.catch((error) => {
console.log(error);
});
}
}
and then in the other class I run this get method right after the post method
class Game extends React.Component {
getUserInfo() {
fetch("http://localhost:8080/api/users" , {mode: "cors"})
.then((res) => res.json())
.then((data => {
this.setState({ usersInfoArray: data})
var _userid = data[data.length-1].id;
var _username = data[data.length-1].username;
var _bestscore = data[data.length-1].bestscore;
this.setState({ userid: _userid, username: _username, bestscore: _bestscore});
}))
}
}
componentDidMount(){
this.getUserInfo();
this.render();
}
I guess you may call postUserInfo() in another component then move to new Component
then after component mount, call getUserInfo()
Am i right?
If so
your navigate to(or create) other component logic must in postUserInfo()
near
.then((data => {console.log(data)}))
Probably the easiest way to do this is to maintain a dataPosted flag in App's state and pass that flag to the Game component. If the dataPosted flag is true, then load the data.
App.jsx
import Game from "./components/Game/Game";
class App extends React.Component {
constructor() {
super();
this.state = { dataPosted: false }
}
postUserInfo(){
fetch("http://localhost:8080/api/users" , {
method: "post" ,
mode: "cors",
headers: {
"Content-type": "application/json",
},
body:JSON.stringify({username:this.state.userInput, bestscore:0})
})
.then((res) => res.json())
.then(data => {
this.setState({ dataPosted: true })
})
.catch((error) => {
console.log(error);
});
}
}
render() {
<Game dataPosted={this.state.dataPosted} />
}
}
Game.jsx
class Game extends React.Component {
componentDidUpdate() {
if (this.props.dataPosted) {
this.getUserInfo();
}
}
getUserInfo() {
fetch("http://localhost:8080/api/users" , {mode: "cors"})
.then((res) => res.json())
.then((data => {
this.setState({ usersInfoArray: data})
var _userid = data[data.length-1].id;
var _username = data[data.length-1].username;
var _bestscore = data[data.length-1].bestscore;
this.setState({ userid: _userid, username: _username, bestscore: _bestscore});
}))
}
}

Cannot get Ajax result from a Vue method to data()s returned variables

I have this component, I have just started working with components until this point where there I am trying to fetch data via ajax, when console.loging inside the method - I get the actual result, but the result isn't returned.
What is it that I'm not understanding (In vanilla js when doing the same from an object, it works fine.. so why in Vue it doesn't work? What's the reason from behind the scenes?)
How can I fetch data using $.ajax?
What are my other alternatives and why? (I know of Axio, never used it, not sure why to use it if I can use fetch, which btw, fetch didn't work for me too - that's why I went back to $.ajax).
index.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import axios from 'axios';
import VueAxios from 'vue-axios'
Vue.use(VueRouter);
Vue.use(VueAxios, axios);
const Dashboard_testcomponent = () => import('../vue/dashboard/test/testcomponent.vue');
let routes = [
{
path: '/main',
component: Dashboard,
children: [
{
path: 'testcomponent',
component: Dashboard_testcomponent
}
]
}
];
window.router = new VueRouter({
mode: 'history',
routes
});
testcomponent.vue:
<script>
import Form from "../../components/Form.vue";
import Tabs from "../../components/Tabs.vue";
export default {
name: 'testcomponent',
components: {
Form,
Tabs
},
data() {
return {
reportType: 'testreport',
dates: {},
list: {}
}
,
created() {
},
mounted() {
},
destroyed() {
},
watch: {
},
methods: {
// Submit form
formSubmit: function(data) {
console.log('Submit form here');
console.log(data);
// SetLoader();
this.list = this.getList();
console.log(this.getList());
console.log(this.List);
},
// Fetch List By List type
getList: function() {
axios.post('/call/api/getList', {
'reportType': this.reportType
})
.then(function (response) {
if (response.status === true) {
console.log(response);
return response.data;
}
})
.catch(function (error) {
console.log(error);
});
}
}
}
</scrip1t>
<templat e>
<Form
:useGroupFilter="true"
:useDateRange="true"
#submit="formSubmit"
/>
</template>
In you code getList is not returning anything, because axios.post is async function and executes later.
You should assign response data in .then callback.
Something like:
getList: function() {
axios.post('/call/api/getList', {
'reportType': this.reportType
})
.then(function (response) {
// if (response.status === true) { (if 'then' fired means that it succeeded already)
console.log(response);
this.list = response.data;
// }
})
.catch(function (error) {
console.log(error);
});
}
Install Axios for in your project directory
$ npm install axios
import in app.js or in the component which you want
<script>
//optional import for individual component
import axios from "axios";
</script>
//if you have imported in app.js
Vue.use(axios);
then make axios call like:
let reqData = {
p_Params1: '',
p_Params2: '',
p_Params3...: ''
};
axios({
method: "post",
url: "http://127.0.0.1/sample_sub/sample.ext",
crossdomain: true,
data: $.param(reqData),
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
})
.then(response => {
//your resposne here
})
.catch(error => console.log(error));
Note! by default axios does not parse the data to json so use $.param

Why are Relay Modern QueryRenderer render props undefined?

This is my first attempt at using Relay Modern.
Fetching for a specific User from a PostgraphQL GraphQL Server.
It is fetching the data successfully but not passing to render function:
import {createFragmentContainer, QueryRenderer, graphql} from 'react-relay'
import environment from 'environment'
#CSSModules(styles) export default class Profile extends Component {
render() {
var {props: {children}} = this
return (
<QueryRenderer
environment={environment}
query={graphql`
query ProfileQuery {
userById(id: "f0301eaf-55ad-46db-ac90-b52d6138489e") {
firstName
userName
}
}
`}
render={({error, relayProps}) => {
if (error) {
return <div>{error.message}</div>
} else if (relayProps) {
...
}
return <div>Loading...</div>
}}
/>
)
}
}
Only "Loading..." is rendered.
I am guessing because it successfully fetches data that the graphql server and environment are ok.
I am not using React 16 and the project also uses Redux.
Any suggestions please as to why relayProps wouldn't have a value (e.g. relayProps.user)?
One further thing that may help, the environment (file) is in the main application and the QueryRenderer and components are in an imported npm package (to be shared across a number of applications). As mentioned, the query seems to work fine so I did not think this was a problem. I also run the relay compiler on the package but not the main application since there are no relay components there.
Just in case it's needed the environment is setup using:
const {
Environment,
Network,
RecordSource,
Store,
} = require('relay-runtime')
// Instantiate Store for Cached Data
const store = new Store(new RecordSource())
// Create Network for GraphQL Server
const network = Network.create((operation, variables) => {
// GraphQL Endpoint
return fetch(config.gqlapiProtocol + "://" + config.gqlapiHost + config.gqlapiUri + "/a3/graphql" , {
method: 'POST',
headers: {
'Content-Type': "application/json",
'Accept': 'application/json',
},
body: JSON.stringify({
query: operation.text,
variables,
}),
}).then(response => {
return response.json()
})
})
// Instantiate Environment
const environment = new Environment({
network,
store,
})
// Export environment
export default environment
props are not relayprops
render={({ error, props }) => {
if (error) {
return <div>{error.message}</div>;
} else if (props) {
...
}
return <div>Loading...</div>;
}}
and
fetch(GRAPHQL_URL, {
method: 'POST',
get headers() {
return {
'Content-Type': 'application/json',
'Accept': 'application/json',
};
},
body: JSON.stringify({
query: operation.text, // GraphQL text from input
variables
})
})
.then(response => response.json())
.then((json) => {
// https://github.com/facebook/relay/issues/1816
if (operation.query.operation === 'mutation' && json.errors) {
return Promise.reject(json);
}
return Promise.resolve(json);
})
);

Categories

Resources