Why does vue.js alter my JSON data? - javascript

I want to return data from my API and display it in a vue.js project.
The data is:
{
"pages":[
{
"id":3,
"slug":"over-mij",
"updated_at":"2017-12-25T11:16:21+01:00",
"created_at":"2017-12-25T10:56:21+01:00",
"title":"Over mij",
"content":""
},
{
"id":6,
"slug":"mijn-cv",
"updated_at":"2017-12-25T11:07:29+01:00",
"created_at":"2017-12-25T11:07:29+01:00",
"title":"Mijn cv",
"content":null
}
],
"current_user":null
}
Then I'm using vue-resource to load the data from my API page in a seperate module of vuex:
const actions = {
initPages({commit}) {
Vue.resource('pages').get({}).then(function(response) {
if (response) {
response.json().then(data => {
state.pages = data;
});
}
});
}
}
The problem however is when I check what's inside the state.pages, this contains:
{
"pages": {
"pages": [
{
"id": 3,
"slug": "over-mij",
"updated_at": "2017-12-25T11:16:21+01:00",
"created_at": "2017-12-25T10:56:21+01:00",
"title": "Over mij",
"content": ""
},
{
"id": 6,
"slug": "mijn-cv",
"updated_at": "2017-12-25T11:07:29+01:00",
"created_at": "2017-12-25T11:07:29+01:00",
"title": "Mijn cv",
"content": null
}
],
"current_user": null
}
}
For some weird reason my JSON response is altered, I've already tried setting state.pages to data.pages and this just eliminates the first pages object but not the second one.
When I set my state.pages to data.pages[0] it does work, does anyone know why this is happening?
Even when I use mutations, I still have the same issue:
module of store.js:
import Vue from 'vue';
const state = {
pages: []
}
const mutations = {
'setPages' (state, pages) {
state.pages = pages;
}
}
const getters = {
pages(state) {
return state.pages;
},
page(state) {
return keyword => state.pages.find(function(page) {
return page.slug === keyword;
});
}
}
const actions = {
initPages({commit}) {
Vue.resource('pages').get({}).then(function(response) {
if (response) {
response.json().then(data => {
commit('setPages', data.pages);
});
}
});
}
}
export default {
state,
getters,
mutations,
actions
}

Related

Using strapi V4 graphql and nextjs - filters not work

I´m using strapi V4 with the graphql extension. When i´m use filters with variables in the graphql Playground there are no problems.
query getOrdersFilterList($searchstring: String!) {
orders(filters: { customer: { contains: $searchstring } }) {
data {
attributes {
number
customer
name
article
}
}
}
}
Query Variables:
{
"searchstring": "zi"
}
When i use filters with Postman no problems.
query getOrdersFilterList($searchstring: String) {
orders(filters: {customer: { containsi: $searchstring}}) {
data {
attributes {
number
customer
name
article
}
}
}
}
Graphql Variables :
{
"searchstring": "zi"
}
The result is like expected:
{
"data": {
"orders": {
"data": [
{
"attributes": {
"number": "30072",
"customer": "Stauder Zimmerei",
"name": "Hagmann Habsburgerstr.",
"article": "Stahlteile "
}
},
{
"attributes": {
"number": "22-02-015 A",
"customer": "Ziebarth Wolfgang",
"name": "Austr. 1 a",
"article": "Aussengeländer "
}
},
{
"attributes": {
"number": "30013",
"customer": "Ziser",
"name": "Bürklinstraße 7, Lahr",
"article": "Geländer mit Mlichglas "
}
}
]
}
}
}
Now my nextjs app code:
export const getOrdersFilterList = async (page, pageSize, searchstring) => {
const data = await client.query({
query: gql`
query getOrdersFilterList($searchstring: String) {
orders(filters: {customer: { contains: $searchstring}}){
data {
attributes {
number
customer
name
article
}
}
}
}`,
variables: {searchstring}
})
Variables same as above ( searchstring come from the call of the function )
{
"searchstring": "zi"
}
this is what i get on the console (Firefox):
" Object { data: {…}, loading: false, networkStatus: 7 } "
I spend days to search. I can´t find a clue
Anyone can help ?
solved !
The Problem was the Variable
{
"searchstring": "zi"
}
In every Tutorial or example i find it like above.
But the only thing your Variable must contain is
zi
let´s explain in the code :
export const getOrdersFilterList = async () => {
// this is the variable
const searchstring = "zi"
// thats all
const data = await client.query({
query: gql`
query getOrdersFilterList($searchstring: String) {
orders(filters: {customer: { containsi: $searchstring}}){
data {
attributes {
number
customer
name
article
}
}
}
}`,
variables: {searchstring}
})

Transform data from fetch with React

I have retrieved data from an API, and now trying to transform the data to send a POST request. I want to group two User ID's that match, and POST their common cities in a array instead of separate objects.
For example, data I retrieve looks like this:
{
"events": [
{
"city": "city-1",
"user": "d1177368-2310-11e8-9e2a-9b860a0d9039"
},
{
"city": "city-2",
"user": "d1177368-2310-11e8-9e2a-9b860a0d9039"
}
]}
I want my POST request data to look similar to this:
{
"user": {
"d1177368-2310-11e8-9e2a-9b860a0d9039": [
{
"city": [
"city-1",
"city-2"
]
}]}}
So far this is my React component for the request:
import React, { useEffect, useState } from "react";
import axios from "../data/axios";
export default function Events({ fetchEvents }) {
const [events, setEvents] = useState([]);
useEffect(() => {
async function fetchData() {
const requests = await axios.get(fetchEvents);
setEvents(requests.data.events);
return requests;
}
fetchData();
}, [fetchEvents]);
//here is my issue:
function createSessions(user, city) {
if (user === user) {
}
}
Thank you
Iterate over the events array, reducing it into an object with a user object property. The user object has the user values from the events array elements as key and the cities are pushed into a city array property.
events.reduce(
(result, el) => {
if (!result.user[el.user]) {
result.user[el.user] = [{ city: [] }];
}
result.user[el.user][0].city.push(el.city);
return result;
},
{ user: {} }
);
const data = {
events: [
{
city: "city-1",
user: "d1177368-2310-11e8-9e2a-9b860a0d9039"
},
{
city: "city-2",
user: "d1177368-2310-11e8-9e2a-9b860a0d9039"
}
]
};
const data2 = data.events.reduce(
(result, el) => {
if (!result.user[el.user]) {
result.user[el.user] = [{ city: [] }];
}
result.user[el.user][0].city.push(el.city);
return result;
},
{ user: {} }
);
console.log(data2);

Error: A required parameter (productId) was not provided as a string in getStaticPaths for /products/[productId]

I would like to show 3 products from a JSON. I'm trying to do a NextJS web application. I'm just learning, and when I replicate the tutorial is everything correct, but I'm doing my own changes, and trying to create something different, but it doesn't work.
Thanks to all!
[
{
"id": "price_1JDUeIIpi9NgmDuQlNYIwAlP",
"title": "HarryPotter1",
"category": "Cuento",
"image": "/images/harrypotter1.jpeg",
"price": 20
},
{
"id": "price_1JDUe4Ipi9NgmDuQh9nA4B9E",
"title": "Harry Potter2",
"category": "Novela",
"image": "/images/harrypotter2.jpeg",
"price": 10
},
{
"id": "price_1JDUdqIpi9NgmDuQGOQO9HGj",
"title": "Harry Potter3",
"category": "Ensayo",
"image": "/images/harrypotter3.jpeg",
"price": 25
}
]
]
In different routes with Link. This is my [productId].js file final part:
export async function getStaticProps({ params = {} }) {
const product = products.find(({ id }) => `${id}` === `${params.productId}`);
return {
props: {
product
},
};
}
export async function getStaticPaths() {
const paths = products.map((product) => {
const { id } = product;
return {
params: {
productId: id,
},
};
});
return {
paths,
fallback: false
};
}
I'm getting from Chrome: Error: A required parameter (productId) was not provided as a string in getStaticPaths for /products/[productId]
I can only assume based on the error description, that:
const { id } = product;
return {
params: {
productId: id,
},
};
In this part of the getStaticPaths function, you are supposed to provide the id for productId as a string (might be a number on its own).
So you would want to try changing it to this:
const { id } = product;
return {
params: {
productId: id.toString(),
},
};
Let me know if this is what you were looking for.

How to update entire dictionary using setState [duplicate]

This question already has answers here:
The useState set method is not reflecting a change immediately
(15 answers)
Closed 2 years ago.
I believe its quite simple but I am not able to figureout how to replace entire object using useState and setState. Here I have the empty data:
const emptyData = {
"foos": {},
"bars": {}
};
const [chartData, setChartData] = useState(emptyData);
I successfully get JSON response (response_json) from my API call which looks like below:
{
"foos": {
"foo1": {
"id": "foo1",
"foo_position": {
"pos_x": 300,
"pos_y": 100
},
},
"foo2": {
"id": "foo2",
"foo_position": {
"pos_x": 300,
"pos_y": 300
},
},
"foo3": {
"id": "foo3",
"foo_position": {
"pos_x": 300,
"pos_y": 500
},
}
},
"bars": {
"bar1": {
"id": "bar1"
},
"bar2": {
"id": "bar2"
}
}
}
Now I want to replace entire chart data or foos and bars which doesnt seem not to happen:
useEffect(() => {
async function handlePageLoad() {
const apiURL = getDataUrl(id);
const response = await getData(apiURL);
if (response.status === 200) {
const response_json = await response.json();
setChartData(response_json);
alert(JSON.stringify(chartData));
}
}
handlePageLoad();
}, []);
I also tried but no success:
setChartData({ ...chartData, foos: response_json.foos});
Edit: I put an alert to see if the data has been changed or not but I see following in the alert message which is similar to the initial data:
{"foos":{},"bars":{}}
Any help is much appreciated
I think you just need to wait for the mutation to be merged. try the following to log the state after it has been updated
useEffect(() => {
async function handlePageLoad() {
const apiURL = getDataUrl(id);
const response = await getData(apiURL);
if (response.status === 200) {
const response_json = await response.json();
setChartData(response_json);
// alert(JSON.stringify(chartData));
}
}
handlePageLoad().then(() => alert(JSON.stringify(chartData)));
}, [])

Reactjs: Why my props aren't being updated?

I need to update my props in order to render new data.
I have a view with a list of dealers for a casino game. That list is OK, the problem comes up when you try to add a new dealer, the dealer doesn't display in the view, yo have to reload the page in order to see the new change.
Let me show you my code starting in the actions
action
class CreateDealersActions {
constructor () {
this.generateActions('createDealerSuccess');
}
createDealer (data) {
const that = this;
that.dispatch();
axios.post(`${API_ENDPOINT}/create-dealer/create-dealer`, data)
.then(function success (response) {
that.actions.createDealerSuccess({response});
})
}
}
store
class GetDealersStore {
constructor () {
this.state = {
dealerData : null,
};
}
#bind(GetDealersActions.dealerDataSuccess)
dealerDataSuccess (data) {
this.setState({
dealerData : data,
});
}
#bind(CreateDealersActions.createDealerSuccess)
createDealerSuccess (data) {
this.setState({
dealerData : data,
});
}
}
the dealerDataSuccess() is the function I call when the view loads in order to render the list of dealers, and createDealerSuccess() is the one called when you attempt to add a new dealer.
here you will see what every function returns
if you put in dealerDataSuccess() console.log(JSON.stringify(data));
{"dealersData": [{
"DealerId":"1",
"DealerName":"Carmen",
"NickName":"Carmen",
"Picture":"url",
"Active":"1",
"LegalId":"13",
"TypeId":"1"}
]}
but if you put in createDealerSucess() console.log(JSON.stringify(data)); it returns something like this:
{
"response": {
"data": {
"success": "New dealer successfully inserted."
},
"status": 200,
"statusText": "OK",
"headers": {
"content-type": "application/json; charset=utf-8"
},
"config": {
"method": "post",
"headers": {
"Content-Type": "application/json;charset=utf-8"
},
"transformRequest": [
null
],
"transformResponse": [
null
],
"url": "http://localhost:1102/services/create-dealer/create-dealer",
"data": {
"DealerName": "my Name",
"CardId": "1221",
"NickName": "newName",
"Picture": "url",
"Active": "1",
"LegalId": "321321",
"TypeId": "1"
}
}
}
}
the component code
component
#connectToStores
export default class Dealers extends Component {
static contextTypes = {
router : React.PropTypes.func,
}
constructor (props) {
super(props);
this.state = {}
}
componentWillMount () {
GetDealersActions.getDealers();
}
static getStores () {
return [ GetDealersStore ];
}
static getPropsFromStores () {
return {
...GetDealersStore.getState(),
}
}
render () {
return (<html for component>);
}
_addDealer = () => {
CreateDealersActions.createDealer({
DealerName : this.refs.DealerName.getValue(),
CardId : this.refs.CardId.getValue(),
});
}
}
now in the component part there is componentWillMount(), if you put console.log(JSON.stringify(this.props)); it returns
{"params":{},"query":{},"dealerData":null}
and if you put in _addDealer console.log(JSON.stringify(this.props)); where it suppose to add the new dealer you get the whole props but without the last dealer you add, so you have to refresh the page in order to see the new dealer in the view/screen.
What do you think is going on here ?
PS: if you similar question about this from me, take into account that in the other question I was 2 using different stores, here I am using just one
EDIT
the Dealers component is within a tab named management, which is this one:
const menuItems = [
{ route : 'dealers', text : 'Dealers' },
{ route : 'game-info', text : 'Game Info' },
{ route : 'player-info', text : 'Players Info' },
{ route : 'money', text : 'Money' }
];
export default class Management extends React.Component {
static propTypes = {
getActivePage : React.PropTypes.func,
menuItems : React.PropTypes.arrayOf(React.PropTypes.object),
}
static contextTypes = {
router : React.PropTypes.func,
}
render () {
return (
<div>
<TabsMainMenu menuItems={menuItems} getActivePage={this._getActivePage} />
<RouteHandler />
</div>
);
}
_getActivePage = () => {
for (const i in menuItems) {
if (this.context.router.isActive(menuItems[i].route)) return parseInt(i, 10);
}
}
}

Categories

Resources