How to define a state with JSON data (using react and axios) - json

I am a little confused about how to go about this. So I have this JSON file called posts.json.
[
{
"id": 1,
"title": "Kylie Jenner",
"content": "Social Media Public Figure",
"disclaimer": "*Disclaimer: This user may have comment filtering turned on",
"slug": "hello-world",
"img" : "https://ilarge.lisimg.com/image/16801290/1080full-kylie-jenner.jpg",
"banner" : "https://i.pinimg.com/originals/a5/2b/96/a52b963809c7e64e538b113cccf61dda.jpg",
"handle": "kyliejenner",
"handlelink" : "https://www.instagram.com/kyliejenner/"
}
]
I am currently trying to make a GET request to an API(url) that also includes specific data from my json file. In this case it will include the celebs handle. This is what I have setup here on Graphs.js.
export default class Graph extends Component {
constructor(props) {
super(props);
}
state = {
handle: '',
}
componentDidMount() {
axios.get('http://localhost:5000/celebs/' + handle)
.then(response => {
this.setState({ celebs: response.data })
})
.catch((error) => {
console.log(error);
})
}
}
I am aware this isn't right as this is where I am stuck. "+ handle" is to come from the json file. I want to make a request to the url where /handle will match the handle directly from json file as defined "handle": "#kyliejenner". But I keep getting an error saying 'handle' is not defined no-undef. No matter how I do it, I can't seem to get it right and keep getting the same error.
So how do I go about defining handle with the data from the json file passed into it? More specifically the handle data.
I apologize in advance if this isn't clear. Please let me know if you need further clarrification.

You can store the json in a different file assign the data to an object and you can import it like this.
import posts from 'posts.js';
Now you have access to the posts object in your component, so you can just access it using
const handle = posts[i].handle; //pass the index of array(i);

As pointed in the comment by Sean, your local state is a bit wrong. You should declare it like this:
constructor(props) {
super(props);
this.state = {handle: ''};
}
And use it like this:
axios.get('http://localhost:5000/celebs/' + this.state.handle)
Or, using Template Literals:
axios.get(`http://localhost:5000/celebs/${this.state.handle}`)
More info in the docs: https://reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class

Related

Can I create record in Ember without the record name

My Backend Rails API consumes POST requests in the form of
{
"name": "Mark White",
"email" : "mark#xyz.com"
}
Have tried this in Postman and this creates a record successfully.
In my ember frontend, Im using the following code to create a new record, from a form input:
app/routes/addUser.js
import Ember from 'ember';
export default Ember.Route.extend({
actions: {
addUser(){
let formData = {
"name": this.controller.get('name'),
"email": this.controller.get('email')
};
let newUser = this.store.createRecord('user',formData);
newUser.save();
}
}
});
which generates the request as
{
"user": {
"name": "Mark White",
"email" : "mark#xyz.com"
}
}
which my backend is not prepared to handle and throws an error.
Any way I can quickly conform to the json format that works for me in Postman.
When the question is along the lines with the "How can I change my payload to server for it to be in a certain format?" then you should have a look at customizing a serializer.
But it looks like for solving your problem you might wanna take the standard JSON Serializer; in your app/serializers/application.js just type the following:
import JSONSerializer from '#ember-data/serializer/json';
export default class ApplicationSerializer extends JSONSerializer {
// ...
}
Note that it's for the Ember.js v4, according to your example you're using a bit older version so just adjust the syntax accordingly.

Fetch data from JSON local file in React

I would need some help to fetch some data in a local file calling data.json to my React component. The data is very simple, but when i tried to connect with my component, all I have in the component appear less than the information I added from the data file.
this is my data.json:
{ "data": [
{ "id": "1",
"name": "john"
},
]}
...and this is my component where i need to fetch the data and where everything is working less than the information I want to connect and appear completely blank.
This is the function where i past the information in the first instant to send the information to the state.
function RenderFoo({data, name}) {
return (
<div>{data.name}</div>
)}
export default class Example extends Component {
constructor(props) {
super(props);
this.state = {
data : [data]
}}
render() {
const dataExample = this.state.data.map((element) => {
return (
<div key={element.url}>
<RenderFoo data ={ element }/>
</div>
)})
return (
<div>
<Card >
{dataExample}
</Card>
</div>)
The screen appear blank in the part of the component that I connect the data but without any error in the other part of the component where everything is working. I think the sintaxis to get the information is not right any reason don't read the data.
And if I change data.name in the function is giving error. I don't know if I'm missing the key or so.
Moving all the data to the main component is worthy neither because I will need to increase the data after and I will thousands of lines, and create a complete back end would be pointless for this kind of application
Thanks
Your state has a property data which is an array. Each element of that array is an object with properties id and name -- and maybe url?
So then what are the props supposed to be here:
function RenderFoo({data, name}) {
return (
<div>{data.name}</div>
)}
Does RenderFoo take a single property data which is the the whole data object? Or does it take the properties of data as individual props? Either is fine, but it feels like you are mixing the two. So remove name from the props.
<div key={element.url}>
Do all elements in your data have a url property? I'm only asking because your sample just shows name and id.
this.state = {
data : [data]
}}
This also looks suspect to me. You are taking the variable data and making it a single element in an array. I'm not sure exactly what your data variable looks like, but I think you probably want to set it as the entire state, this.state = data.
Try this:
import React, { Component } from "react";
import json from "./data";
function RenderFoo({ data }) {
return <div>{data.name}</div>;
}
export default class Example extends Component {
constructor(props) {
super(props);
this.state = {
data: json.data
};
}
render() {
return (
<div>
{this.state.data.map((element) => (
<div key={element.id}>
<RenderFoo data={element} />
</div>
))}
</div>
);
}
}
I removed the <Card> component because I don't know where you imported it from, but you can easily add it back it.

React Native - make dummy db get real data from api

I am quite new to React Native and JS and have recently purchased a React Native template which has a Dummy DB.
Ideally Id like it to pull data from an external JSON (api) which is being generated from a PHP website we already have running.
Here is the Dummy data file:
import {
DoctorModel,
TreatmentModel,
CampaignModel,
EventModel
} from "../models";
export const doctorsList: DoctorModel[] = [ { ##JSON HERE## } ];
export const treatmentsList: TreatmentModel[] = [ { ##JSON HERE## } ];
export const campaignList: CampaignModel[] = [ { ##JSON HERE## } ];
export const eventList: EventModel[] = [ { ##JSON HERE## } ];
I want it to export as the same values as above so it will work seamlessly with the current app configuration.
I have tried the following...
export const doctorsList: DoctorModel[] = () =>
fetch(' ##LINK TO API## ')
.then((response) => response.json());
But got this error:
Type '() => Promise<any>' is missing the following properties from type 'DoctorModel[]': pop, push, concat, join, and 27 more.
I have looked all over here and other platforms for a solution but cant find anything.
Again the ideal outcome would for it to work exactly how it would if I manually typed the JSON in as seen in the first code snippet.
Any help is much appreciated, still trying to wrap my head around React! :)
This doesn’t look like a react problem, but a typescript one. Typescript does a type inference from your return value to check and see if it matches what you’ve stated.
In short: you’ve just declared your types wrong.
The function doesn’t return a DoctorModel[] it’s returning Promise<DoctorModel[]>
export const doctorsList: Promise<DoctorModel[]> = () =>
fetch(' ##LINK TO API## ')
.then((response) => response.json() as DoctorsModel[]);
So changing that line ought to make your typescript compiler chooch again!

TypeScript / Angular 2 creating a dynamic object deserializer

So I am coming from a background of C# where I can do things in a dynamic and reflective way and I am trying to apply that to a TypeScript class I am working on writing.
Some background, I am converting an application to a web app and the backend developer doesn't want to change the backend at all to accommodate Json very well. So he is going to be sending me back Json that looks like so:
{
Columns: [
{
"ColumnName": "ClientPK",
"Label": "Client",
"DataType": "int",
"Length": 0,
"AllowNull": true,
"Format": "",
"IsReadOnly": true,
"IsDateOnly": null
}
],
Rows:[
0
]
}
I am looking to write an Angular class that extends Response that will have a special method called JsonMinimal which will understand this data and return an object for me.
import { Response } from "#angular/http";
export class ServerSource
{
SourceName: string;
MoreItems: boolean;
Error: string;
ExtendedProperties: ExtendedProperty[];
Columns: Column[];
}
export class ServerSourceResponse extends Response
{
JsonMinimal() : any
{
return null; //Something that will be a blank any type that when returned I can perform `object as FinalObject` syntax
}
}
I know StackOverflow isn't for asking for complete solutions to problems so I am only asking what is one example taking this example data and creating a dynamic response that TypeScript isn't going to yell at me for. I don't know what to do here, this developer has thousands of server-side methods and all of them return strings, in the form of a JSON or XML output. I am basically looking for a way to take his column data and combine it with the proper row data and then have a bigger object that holds a bunch of these combined object.
A usage case here after that data has been mapped to a basic object would be something like this.
Example:
var data = result.JsonMinimal() as LoginResponse; <-- Which will map to this object correctly if all the data is there in a base object.
var pk = data.ClientPK.Value;
I'm not exactly sure I understand, but you may want to try a simple approach first. Angular's http get method returns an observable that can automatically map the response to an object or an array of objects. It is also powerful enough to perform some custom mapping/transformation. You may want to look at that first.
Here is an example:
getProducts(): Observable<IProduct[]> {
return this._http.get(this._productUrl)
.map((response: Response) => <IProduct[]> response.json())
.do(data => console.log('All: ' + JSON.stringify(data)))
.catch(this.handleError);
}
Here I'm mapping a json response to an array of Product objects I've defined with an IProduct interface. Since this is just a "lambda" type function, I could add any amount of code here to transform data.

Vue js external data object

I'm just starting out and have gone through the Vue guide. I've got some basic grasp on imports and exports of ES6 but wanted to know the ideal way of doing this.
I'll have several components that need an original single source of data that i'll need to individually manipulate from there. Ideally I want that data to be in a separate file so that others can manipulate it.
I can figure out to do this via jquery ( seen below ) but I don't really need to make a call as the json file will be internal:
module.exports = {
data: function () {
return {
msg: 'hello',
whatever : 'hi'
}
},
created : function() {
this.fetchData();
},
methods : {
fetchData : function() {
console.log("WORKING");
var self = this;
$.get( apiURL, function( data ) {
self.items = data;
console.log(data);
});
}
}
}
But I also don't want to have all the data be in the App.vue file. I need it somewhere else and then need it to replace my data.
Is the best way to do this to create another Vue file with no template or styling and just create it's own module.exports data object? Say mydata.vue:
module.exports = {
data: function () {
_mydata = {
items : [
{case:'caseone'},
{case:'casetwo'}
],
otheritems : [
{case:'caseone'},
{case:'casetwo'}
]
}
}
}
And then somehow replacing this data object in mydata.vue with the data object in app.vue with imports ( main. js ) ?
import Vue from 'vue'
import App from './App.vue'
import Data from './SiteData.vue'
Just wanted to check if this was the ideal way/i'm on the right path...or if there is an easier way to have a central data object in a different file for all my components?
What I have done is to manage my data in a json file. I think that the approach of use separate files for initial data is cool for small apps. Bigger apps need something more usefull like Vuex.
I don't think it is a good idea to manage a .vue file, as those files are meant to be handled by some module budled system, with the correspondind vue transformation, not the case of the data object.
My approach was this: I had a data.json file
data.json
{
"component1": {
"someData": "someValue",
...
},
...
"componentN": {
"someOtherData": "someOtherValue"
}
}
And then I import that data in the corresponding component
componentN.vue
<template>
</template>
<script>
import { componentN } from './data.json'
export default {
data () {
return componentN
}
}
</script>
Note that:
I used a single file for manage data, however you can split it in a file for every component, for example.
As you can see, this approach can become a mess with medium apps, I don't want to even imagin it in big apps, so be careful.