How to insert data to JSON file dynamically? - json

json file img
Note: I wanna insert data without write that into .json file. such as Angularfire2 database.
user = {
name: 'Arthur',
age: 21
};
const options = {Headers, responseType: 'json' as 'blob'};
this.httpService.put('assets/data/ex.json', this.user, options).subscribe(
data => {
console.log(data);
},
(err: HttpErrorResponse) => {
console.log (err.message);
}
);

You can directly access the object using dot operator
user = {
name: 'Arthur',
age: 21
};
const options = {Headers, responseType: 'json' as 'blob'};
this.httpService.put('assets/data/ex.json', this.user, options).subscribe(
data => {
console.log(data);
data.user.lastName = 'stackoverflow';
},
(err: HttpErrorResponse) => {
console.log (err.message);
}
);

Related

Angular, httpClient in service retrieves CSV data and sends JSON data to component

I'm trying to create a service in an Angular project that retrieves CSV data from an API server and passes JSON to the component.
The console displays nice JSON data from the service, but the component displays much earlier Component data: UNKNOWN.
I use the csvtojson module to convert CSV to JSON
Component
getData(): any {
this.storeService.getData()
.subscribe(data => {
console.log('Component data: ', data);
}, error => {
console.log(error);
});
}
Service "storeService"
getData(): Observable<any> {
return this.httpClient
.get('http://llocalhost:3000/user/11', { responseType: 'text' as 'text' })
.pipe(
map((data) => {
csv({
noheader: true,
trim: true,
delimiter: ';'
})
.fromString(data)
.then(jsonData => {
// This is OK - I can see a JSON data
console.log('Service jsonData', jsonData);
// How to send this jsonData to component?
return jsonData;
})
})
)
}
Thanks for your help.
This issue can be resolved easily by creating a behaviorSubject and assigning the fetched data to that variable.
And when you need to access the data in your component. ts file, you can simply subscribe to the behaviorSubject and get the data.
Once subscribed, you can simply call this.storeService.getData(); and get the updated value automatically(because you have subscribed to the behaviorSubject, it will update the component on value change).
Update your Service "storeService" to the following
yourJsonData: BehaviorSubject<any> = new BehaviorSubject<any>(null);
getData(): Observable<any> {
// DO NOT RETURN HERE
this.httpClient
.get('http://llocalhost:3000/user/11', { responseType: 'text' as 'text' })
.pipe(
map((data) => {
csv({
noheader: true,
trim: true,
delimiter: ';'
})
.fromString(data)
.then(jsonData => {
// This is OK - I can see a JSON data
console.log('Service jsonData', jsonData);
// STORE THIS JSONDATA TO A BEHAVIOUR SUBJECT
this.yourJsonData = jsonData;
})
})
)
}
Now Update your Component.ts file to this....
getData(): any {
this.storeService.getData();
this.storeServiceVariable.yourJsonData.subscribe((data) => {
console.log('Component data: ', data);
});
}
Try Using:
Just return the data in the service and do your thing in the component as follows
Service.ts
getData(): Observable<any> {
return this.httpClient
.get('http://llocalhost:3000/user/11', { responseType: 'text' as 'text' });
}
Component.ts
getData(): any {
this.storeService.getData()
.subscribe(data => {
csv({
noheader: true,
trim: true,
delimiter: ';'
}).fromString(data).then(jsonData => {
// This is OK - I can see a JSON data
console.log('Service jsonData', jsonData);
});
}, error => {
console.log(error);
});
}
I think this will help you....

LOG {"_U": 0, "_V": 0, "_W": null, "_X": null} inside fetch API

I am getting this error when I console data returned from function that fetch data from back end
{"_U": 0, "_V": 0, "_W": null, "_X": null}
here is below the code:
const events_data = [];
function getvals() {
return fetch('http://PCIP:3000/users/timetable')
.then((response) => response.json())
.then((output) => {
return addData(output, events_data);
})
.catch(error => console.log(error))
}
function addData(data, data2) {
data.map((d) => {
data2.push({
title: d.name,
startTime: genTimeBlock(d.day, d.start_time),
endTime: genTimeBlock(d.day, d.end_time),
location: d.location,
extra_descriptions: [d.extra_descriptions],
});
});
}
const data = getvals();
console.log(data); // the error come from here
I have checked answers here but nothing worked for me
fetch API always returns {“_U”: 0, “_V”: 0, “_W”: null, “_X”: null}
How do I access promise callback value outside of the function?
This is because the fetch promise has not return a response yet,
There two way to solve the issue , first you create another async funciton and use it to await for the response
const events_data = [];
async function getvals() {
return fetch('http://PCIP:3000/users/timetable')
.then((response) => response.json())
.then((output) => {
return addData(output, events_data);
})
.catch(error => console.log(error))
}
function addData(data, data2) {
data.map((d) => {
data2.push({
title: d.name,
startTime: genTimeBlock(d.day, d.start_time),
endTime: genTimeBlock(d.day, d.end_time),
location: d.location,
extra_descriptions: [d.extra_descriptions],
});
});
}
async function waitForResponse() {
let resp = await getvals();
return resp;
}
const data = waitForResponse();
console.log(data); // the error come from here
The other way would be using state hooks, passing the return obj to state hook on response.
Function for API call:
export const getApplication = async (URL, headers) => {
let data;
await fetch.get(URL, headers).then(res => data = res.data).catch(err => err);
return data;
}
You can call the API from anywhere after importing it:
getApplication(`your url`, {
headers: {
Authorization: AUTH_TOKEN,
},
}).then(res => console.log(res)).catch(err => console.log(err));

Adding JSON data to React

I have been able to pull data from an API that I built using MongoDB and Express, but am having trouble rendering the nested data to my React component.
For example, if I type in <p>{restaurant.cuisine}</p> I am able to retrieve Burgers, American, but if I try and access {restaurant.status.delivery}, I get an error that says:
Cannot read property 'delivery' of undefined.
But if I {console.log(restaurant.status} I can see the object? I tried turning the object into an array using Object.values, but that didn't work either.
The same thing happens if I try to access the nested objects in {restaurant.images} and {restaurant.geometry}.
Here's a copy of my React hook:
import { useReducer, useEffect } from 'react';
import axios from 'axios';
const ACTIONS = {
MAKE_REQUEST: 'make-request',
GET_DATA: 'get-data',
ERROR: 'error',
};
function reducer(state, action) {
switch (action.type) {
case ACTIONS.MAKE_REQUEST:
return { loading: true, restaurant: [] };
case ACTIONS.GET_DATA:
return {
...state,
loading: false,
restaurant: action.payload.restaurant,
};
case ACTIONS.ERROR:
return {
...state,
loading: false,
error: action.payload.error,
restaurant: [],
};
default:
return state;
}
}
export default function useFetchSingleRestaurant({ id }) {
const [state, dispatch] = useReducer(reducer, {
restaurant: [],
loading: true,
});
useEffect(() => {
dispatch({ type: ACTIONS.MAKE_REQUEST });
axios
.get('http://localhost:4444/restaurants/' + id)
.then((res) => {
dispatch({
type: ACTIONS.GET_DATA,
payload: { restaurant: res.data.restaurant },
});
})
.catch((e) => {
dispatch({
type: ACTIONS.ERROR,
payload: { error: e },
});
});
}, [id]);
return state;
}
I'm accessing it in my SingleRestaurant component:
function SingleRestaurant({ match }) {
const { restaurant } = useFetchSingleRestaurant({ id: match.params.id });
return (
<p>{restaurant.status.delivery}</p>
)
}
And then here's my backend setup as well:
showRestaurant = async (req, res) => {
const restaurant = await Restaurant.findById(req.params.id)
.populate({ path: 'reviews', populate: { path: 'author' } })
.populate('author');
if (!restaurant) {
req.flash('error', 'Restaurant not found.');
return res.redirect('/restaurants');
}
res.send({ restaurant });
};
Until your server request returns restaurant it will be set as the default [] that you have set.
An empty array does not have a property of status, so hence the error.
if you change your default to null:
const [state, dispatch] = useReducer(reducer, {
restaurant: null,
loading: true,
});
And then check for a value:
function SingleRestaurant({ match }) {
const { restaurant } = useFetchSingleRestaurant({ id: match.params.id });
if (!restaurant) return 'Loading'
return (
<p>{restaurant.status.delivery}</p>
)
}
You could also pass back the loading state from your hook and then do a check on that.

My response from api is undefined on frontend

I got list of items from my database mySql and also button 'edit'.
When I clicked edit (by id) I want to see all fields filled by data.
But I only have in my console: undefined
If I tested my api by postman it works fine.
There is how I am getting list.
{
const id = this.actRoute.snapshot.paramMap.get('id');
this.studentApi.GetStudent(id).subscribe((res: any) => {
console.log(res.data);
this.subjectArray = res.data;
console.log(this.subjectArray);
this.studentForm = this.fb.group({
id: [res.id, [Validators.required]],
domain_id: [res.domain_id, [Validators.required]],
source: [res.source, [Validators.required]],
destination: [res.destination]
});
});
}
There is my api.service.ts
GetStudent(id): Observable<any> {
const API_URL = `${this.endpoint}/read-student/${id}`;
return this.http.get(API_URL, { headers: this.headers })
.pipe(
map((res: Response) => {
return res || {};
}),
catchError(this.errorMgmt)
);
}
And there is my route
studentRoute.get('/read-student/:id', (request, response) => {
const id = request.params.id;
con.query('SELECT * FROM students WHERE id = ?', id, (error, result) => {
if (error) throw error;
response.send(result);
});
});
There is response from 'postman'
[
{
"id": 5,
"domain_id": 2,
"source": "tester0700#test.pl",
"destination": "testw#test.pl"
}
]
It seems like the response is an array, containing an object.
In that case, there is no need to use res.data, as that would imply the returned observable, res has a property named data, and that you are trying to access the value within that property. You can simply assign res to the subjectArray property. I am pretty sure res would be defined.
this.studentApi.GetStudent(id).subscribe((res: any) => {
console.log(res);
this.subjectArray = res;
// handle the rest here.
});

React-Native render json from fetch

I have a fetch returning on ComponentDidMount(). Trying to get the response to render on the page.
I have set the state as follows:
this.state = {
loading: true,
file: null,
video: null,
marks: []
};
and my fetch:
componentDidMount() {
return fetch('http://10.0.2.2:8080/marks/createMark')
.then(response => response.json())
.then((data) => {
this.setState({
loading: false,
marks: data.mark
}, () => {
console.log(data.mark);
console.log(this.state.marks);
// const dataMap = data.mark.map((item) => {
// return {
// key: item.id,
// label: item.mark
// };
// });
});
})
.catch(err => console.log(err));
}
Now my render inside of the return:
const { marks } = this.state;
<FlatList
data={marks}
renderItem={({ item }) => <Text>{item.mark}</Text>}
keyExtractor={(item, index) => index}
/>
Do I have to map the data then try to render it??
OUTPUT OF console.log(this.state.marks):
{ _id: '5b61e47a55a0000aa980fab1', mark: 'ItHe', __v: 0 }
The mark is a pseudorandom string that can contain letters and numbers created on the backend
As this.state.marks is an object. First, you need to convert it to this form [{}]. You can do the following changes to make it work.
fetch('http://10.0.2.2:8080/marks/createMark')
.then(response => response.json())
.then((data) => {
let marks = [data.mark]; //Add this line
this.setState({
loading: false,
marks: marks // Change this line
}, () => {
....
Rest of your code
marks is an array but you're not sharing what each object in the array looks like. If it's an array of strings, you're good but if it's an object, you'll need to destructure it and pull out the string you're looking to render.
<Text>{item.mark.someKeyWhoseValueIsAString}</Text