setState doesn't set values - javascript

We got a ReactJS frontend delivered for our school project. We have to make a Laravel backend for it. I'm using an API to fetch the dashboard layout from the database. The current frontend makes use of this variable:
const originalLayouts = getFromLS("layouts") || [];
To set the state from the local storage with this function:
function getFromLS(key) {
let ls = {};
if (global.localStorage) {
try {
ls = JSON.parse(global.localStorage.getItem("rgl-8")) || {};
} catch (e) {
/*Ignore*/
}
}
return ls[key];
}
Where the states are set:
this.state = {
items: originalLayouts.map(function(i, key, list) {
return {
i: originalLayouts[key].i,
x: originalLayouts[key].x,
y: originalLayouts[key].y,
w: originalLayouts[key].w,
h: originalLayouts[key].h,
widget: originalLayouts[key].widget,
minW: originalLayouts[key].minW,
minH: originalLayouts[key].minH,
maxH: originalLayouts[key].maxH
};
}),
selectedOption: '',
newCounter: originalLayouts.length
};
To fetch the data from the database and put the data into the items state I made this function:
loadData = () => {
let dashboardId = 1;
return axios
.get('api/dashboards/' + dashboardId)
.then(result => {
console.log(result);
this.setState({
originalLayouts: result.data,
selectedOption: '',
newCounter: originalLayouts.length
});
console.log(result.data);
})
.catch(error => {
console.error('error: ', error);
})
};
And I call this function in componentDidMount:
componentDidMount() {
this.loadData();
}
When I console log result it shows me this:
data: Array(2), status: 200, statusText: "OK", headers: {…}, config: {…}, …}
config: {adapter: ƒ, transformRequest: {…}, transformResponse: {…}, timeout: 0, xsrfCookieName: "XSRF-TOKEN", …}
data: (2) [{…}, {…}]
headers: {date: "Tue, 23 Oct 2018 08:18:41 +0000, Tue, 23 Oct 2018 08:18:41 GMT", host: "127.0.0.1:8000", x-powered-by: "PHP/7.2.3", x-ratelimit-remaining: "58", content-type: "application/json", …}
request: XMLHttpRequest {onreadystatechange: ƒ, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
status: 200
statusText: "OK"
__proto__: Object
And when I console log result.data I get:
(2) [{…}, {…}]
0: {id: 1, dashboardId: 1, w: 2, h: 5, x: 0, …}
1: {id: 2, dashboardId: 1, w: 2, h: 1, x: 0, …}
length: 2
__proto__: Array(0)
Why is originalLayouts not set with the data from the arrays? Is this because I also have a dashboardId and id in my arrays? I also thought it could be something with setting the states because it makes use of the originalLayouts veriable. Or am I still missing something in my function? I'm not very experienced with React so any help is useful.
Update:
I changed:
this.setState({
originalLayouts: result.data,
selectedOption: '',
newCounter: originalLayouts.length
});
to:
this.setState({
items: result.data,
selectedOption: '',
newCounter: originalLayouts.length
});
This gives me this error:
Uncaught Error: ReactGridLayout: ReactGridLayout.children[0].static must be a boolean!
So that probably means I'm not setting the properties properly now.
Update 2:
In my database the properties moved and static were saved as 0 instead of false. So I changed those properties to false but I still got the same error:
ReactGridLayout: ReactGridLayout.children[0].static must be a boolean!

In your loadData(), you are setting the state of "originalLayouts" but your key in your initial state is "items". Have you tried to do this ?
this.setState({
items: result.data, // Here put items instead of originalLayouts
selectedOption: '',
newCounter: originalLayouts.length
});
Then you can call this.state.items to get your result.data

Related

axios successful request but data is undefined

I'm uploading multiple files separately using axios.
This is the request(all the following code is inside an async function):
const proms = files.map(file => {
let formData = new FormData();
formData.append("file", file);
return axios.post(`/upload/${userId}`, formData)
});
proms will be an array of promises so I proceed to Promise.all it:
const res = await Promise.all(proms)
If I do console.log(res) it shows a successfull response from server as you can see here:
Array(3) [ {…}, {…}, {…} ]​
0: Object { data: {…}, status: 200, statusText: "OK", … }​​
config: Object { timeout: 0, xsrfCookieName: "XSRF-TOKEN", xsrfHeaderName: "X-XSRF-TOKEN", … }​​
data: Object { fieldname: "file", originalname: "612_photo.jpg", encoding: "7bit", … }​​​
destination: ********************​​****
encoding: "7bit"​​​
fieldname: "file"​​​
filename: "/1648309550808-586868206.jpeg"​​​
mimetype: "image/jpeg"​​​
originalname: "612_photo.jpg"​​​
path: ********************​​****
size: 43267​​​
<prototype>: Object { … }​​
headers: Object { "content-length": "395", "content-type": "application/json; charset=utf-8" }​​
request: XMLHttpRequest { readyState: 4, timeout: 0, withCredentials: false, … }​​
status: 200​​
statusText: "OK"​​
<prototype>: Object { … }​
1: Object { data: {…}, status: 200, statusText: "OK", … }​
2: Object { data: {…}, status: 200, statusText: "OK", … }​
length: 3​
<prototype>: Array []
But then when I do console.log(res.data) it is undefined. What is happening here?
your response(res) is An array so you cant access res.data ,try :
res.forEach(item=>{console.log(item.data)})

Vuex is changing object parameter into a component

I have a login form and where the inputs (email & password) are bound. On clicking the button to submit the form, it prevents the default behaviour and uses the login method defined in the Login.vue; Scripts.
While consoling in Login.vue; Scripts; login method, the form data printed out the {email: 'email', password: 'password'} object (desired). Once it is passed to the action (await this.signIn(this.form)), it consoled out a Vue component all of the sudden. I don't understand why this happened and how can this be solved?
Login.vue Component
Form
<form #submit.prevent="login" method="POST">
<input
type="text"
v-model="form.email"
/>
<input
type="password"
v-model="form.password"
/>
<button class="btn btn-primary">Login</button>
</form>
Scripts
<script>
import { mapActions } from 'vuex'
export default {
data() {
return {
form: {
email: '',
password: '',
},
}
},
computed: {
...mapActions('auth', ['signIn']),
},
methods: {
async login() {
/***************************************
* *
* Print out the form data object *
* *
****************************************/
console.log(this.form)
await this.signIn(this.form)
},
},
}
</script>
Vuex - Auth Module
export const actions = {
signIn({ dispatch, commit }, form) {
/***************************************************************
* *
* Print out a Vue component instead of the passed object *
* *
****************************************************************/
console.log(form)
Auth.signInWithEmailAndPassword(form.email, form.password)
.then(user => {
commit('SET_AUTHENTICATED', true)
commit('SET_USER', user.user)
this.$router.push('/')
})
.catch(err => {
console.log(err)
})
},
}
Console logged content
VueComponent {_uid: 4, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
$attrs: (...)
$children: []
$createElement: ƒ (a, b, c, d)
$el: div
$listeners: (...)
$options: {parent: VueComponent, _parentVnode: VNode, propsData: undefined, _parentListeners: undefined, _renderChildren: undefined, …}
$parent: VueComponent {_uid: 3, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
$refs: {}
$root: Vue {_uid: 2, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
$scopedSlots: {$stable: true, $key: undefined, $hasNormal: false}
$slots: {}
$store: Store {_committing: false, _actions: {…}, _actionSubscribers: Array(1), _mutations: {…}, _wrappedGetters: {…}, …}
$vnode: VNode {tag: "vue-component-4", data: {…}, children: undefined, text: undefined, elm: div, …}
form: (...)
login: ƒ ()
signIn: (...)
__VUE_DEVTOOLS_UID__: "1:4"
_c: ƒ (a, b, c, d)
_computedWatchers: {signIn: Watcher}
_data: {__ob__: Observer}
_directInactive: false
_events: {hook:beforeDestroy: Array(1)}
_hasHookEvent: true
_inactive: null
_isBeingDestroyed: false
_isDestroyed: false
_isMounted: true
_isVue: true
_renderProxy: Proxy {_uid: 4, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
_routerRoot: Vue {_uid: 2, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
_self: VueComponent {_uid: 4, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
_staticTrees: null
_uid: 4
_vnode: VNode {tag: "div", data: undefined, children: Array(2), text: undefined, elm: div, …}
_watcher: Watcher {vm: VueComponent, deep: false, user: false, lazy: false, sync: false, …}
_watchers: (2) [Watcher, Watcher]
$data: (...)
$isServer: (...)
$props: (...)
$route: (...)
$router: (...)
$ssrContext: (...)
get $attrs: ƒ reactiveGetter()
set $attrs: ƒ reactiveSetter(newVal)
get $listeners: ƒ reactiveGetter()
set $listeners: ƒ reactiveSetter(newVal)
get form: ƒ proxyGetter()
set form: ƒ proxySetter(val)
__proto__: Vue
As Sumurai8 mentioned, I only need to put the ...mapActions('auth', ['signIn']) in methods and not in computed.
methods: {
...mapActions('auth', ['signIn']),
async login() {
console.log(this.form)
await this.signIn(this.form)
},
},

How do I access properties of objects inside another object

I have an api endpoint form where I am getting data like below. How i will access the values title, short_title etc.
blog: {
paginations: true,
isLoading: false,
particularBlog: [],
count: 13,
next: 'http://127.0.0.1:8000/api/blog/all-blog/?page=2',
previous: null,
results: [
{
id: 47,
user: 1,
title: 'adasd',
short_title: 'asd',
publish: '2019-09-16',
slug: 'adasd',
comments_count: 0,
likes_count: 0
},
{
id: 46,
user: 1,
title: 'adasda',
short_title: 'asdas',
publish: '2019-09-16',
slug: 'adasda',
comments_count: 0,
likes_count: 0
}
]
},
what i have done is
<div>{
this.props.blog && Object.keys(this.props.blog).map((key) => {
return <p>{this.props.blog.results[key]}</p>
})
}</div>
but it is giving error stating paginations' of undefined. Can someone please pointout what i am doing wrong here?
Where is what is happening
Object.keys(this.props.blog).map((key) => { is getting the keys of this.props.blog and this.props.blog.results[key] is trying to access the properties of results with the keys of blog.
What you should do is have another .map with Object.keys of this.props.blog.results
OR
What I think you are trying to do is list all properties on the this.props.blog.results array, so here is what you can do
this.props.blog && this.props.blog.results && this.props.blog.results.map(result=> <p>{result.short_title}</p>
You do .map on the results array and display short_title.
blog.results.map(el => (<div>{el.short_title}</div>))

Formatting json data into table React.js

I have this state defined:
constructor(props){
super(props);
this.state = {
open: false,
customers:[],
customer:{},
products:[],
product:{},
orders:[],
order:{},
newForm:true,
phoneNumbererror:null,
shop:this.props.salon,
value:'a',
showTab:'none',
slideIndex: 0,
};
}
With the following function which contains a fetch, I recieve an array of objects with responseData.
getHistory(){
console.log("Log antes del fetch de customer id");
console.log(this.state.customer._id);
fetch(
DOMAIN+'/api/orders/customer/'+this.state.customer._id, {
method: 'get',
dataType: 'json',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization':'Bearer '+this.props.token
}
})
.then((response) =>
{
return response.json();
})
.then((responseData) => {
let orders = responseData.map((order) => {
return order.orderStatusChange ? Object.assign({}, order, {
status: order.orderStatusChange[0].status
}) : order;
});
this.setState({orders:orders});
console.log("Log del responseData");
console.log(responseData);
console.log(responseData.orderStatusChange[0]);
})
.catch(function() {
console.log("error");
});
}
This function is called in handleCellClick, where I pass some data from the consumer, such as the ID:
handleCellClick(y,x,row){
this.setState({
open:true,
slideIndex: 0,
newForm:false,
customer:{...row}
});
this.getProfiles();
this.getHistory();
}
The JSON object obtained from the fetch and kept within this.state.orders looks like this:
(29) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0:
created:"2017-07-06T15:58:07.958Z"
customer:"59561f3f1d178e1966142ad7"
lastModified:"2017-07-06T15:58:07.958Z"
orderList:[]
orderStatusChange:Array(1)
0:{status: "5", comments: "Creado en back antes de pagar", _id: "595e5e0f60fbf65149916b7c", created: "2017-07-06T15:58:07.958Z"}
length:1
__proto__:Array(0)
shop:"59108159bc3fc645704ba508"
totalAmount:4000
__v:0
_id:"595e5e0f60fbf65149916b7b"
__proto__:Object
As shown previously in the fetch, with this line this.setState({orders:responseData}) I can pass orders to the table where I want the id, date, status and price to be displayed:
<DataTables
height={'auto'}
selectable={false}
showRowHover={true}
columns={HISTORY_TABLE_COLUMNS}
data={this.state.orders}
showCheckboxes={false}
rowSizeLabel="Filas por página"
/>
The table called is:
const HISTORY_TABLE_COLUMNS = [
{
key: '_id',
label: 'Número de pedido',
style:{width: '37%'}
}, {
key: 'created',
label: 'Fecha del pedido',
style:{width: '33%'}
}, {
key: 'status',
label: 'Estado',
style:{width: '13%'}
}, {
key: 'totalAmount',
label: 'Total',
style:{width: '17%'}
}
];
How can I format the price (totalAmount) to have 2 decimals and print next to it the € symbol?
CAPTURE FOR BETTER UNDERSTANDING
This solution works fine with node module material-ui-datatables version 0.18.0
You can use render method in column settings to work on the column data.
const currencyToAppend = '€';
const HISTORY_TABLE_COLUMNS = [
{
....
}, {
....
}, {
key: 'totalAmount',
label: 'Total',
style:{width: '17%'}
render: (amount, all) => {
console.log(amount);
console.log(all);
return amount + ' ' + currencyToAppend;
}
}
];
While iterating data in table please do the following.
totalAmount.toFixed(2) + " €"
Update:
I would suggest this change should be done from backend, But any how for now you can handle it in map iterator where you are setting orders like following
const currencyToAppend = ' €';
let orders = responseData.map((order) => {
return order.orderStatusChange ? Object.assign({}, order, {
status: order.orderStatusChange[0].status
},{
totalAmount: order.totalAmount.toFixed(2) + currencyToAppend
}) : Object.assign({}, order, {
totalAmount: order.totalAmount.toFixed(2) + currencyToAppend
});
});
I hope this will solve your problem.
To complement #dev's answer, I'd suggest to have render the cell as a function as that gives you more control
Check out the codesandox demo https://codesandbox.io/s/0VVwq645L
const HISTORY_TABLE_COLUMNS = [
{
key: "_id",
label: "Número de pedido",
style: { width: "37%" },
value: item =>
<code>
{item._id}
</code>
},
{
key: "created",
label: "Fecha del pedido",
style: { width: "33%" },
value: item => <Time value={item.created} />
},
{
key: "status",
label: "Estado",
style: { width: "13%" },
value: item =>
<span>
{item.status}
</span>
},
{
key: "totalAmount",
label: "Total",
style: { width: "17%" },
value: item => <Amount value={item.totalAmount} currency="€"} />
}
];

how to get json response from restapi in angularjs using $resource?

This is my angularjs code , I am getting response on console put not able to get it in array or json type form
angular.module('user', ['ngResource']).
config(function($httpProvider){
$httpProvider.defaults.headers.common['Accept'] = "application/json"
})
.factory('loginUser', function($resource){
alert("hello amit we done it");
var user=$resource('http://localhost/testtext/index.php/user/login', {}, {
login: {method:'POST'}}
);
console.log(user.login({"user": {"email":"prashant#gmail.com","password":"weldone"}}));
});
console output
Resource {user: Object, $resolved: false, $then: function, $get: function, $save: function…}
$resolved: true
$then: function (b,g){var j=e(),h=
User: Array[1]
0: Object
address: "Noida"
city: "Mathura"
clientid: "clint000000000000009"
country: "India"
email: "prashant#gmail.com"
flag: "0000000000"
fname: "Sushil"
id: "users000000000000041"
lname: "Kumar1"
password: "ee486c2fa50a03b53982cba45ef045c2"
reset_pw_token: ""
session: Object
auth_token: "a1054379e166a085f4f331074c36b6d7"
created_by: null
created_on: null
id: "usaut000000000000187"
scope: "a:11: {i:0;s:19:"user/changepassword";i:1;s:11:"user/logout";i:2;s:12:"role/getrole";i:3;s:17:"ro le/getprivilege";i:4;s:13:"category/save";i:5;s:13:"message/reply";i:6;s:16:"message/classify";i:7;s:12:"message/read";i:8;s:12:"message/list";i:9;s:12:"tag/messages";i:10;s:8:"tag/l ist";}"
updated_by: null
updated_on: "2013-09-03 19:30:52"
user_id: "users000000000000041"
__proto__: Object
state: "UP"
__proto__: Object
length: 1
__proto__: Array[0]
__proto__: Resource
You need to use the success and failure function
user.login({"user": {"email":"prashant#gmail.com","password":"weldone"}},
function(data){
console.log(data[0]) //or data.User[0] or data.user[0] depending upon on your json.
},
function(error) {
console.log(error) // Error details
})

Categories