Axios request get value from nested array in Vue - json

In a .vue file I am trying the get value from an axios get response result which is in a nested array. The code looks like the example below (without a search form for query).
<div class="results" v-if="results">
<p>{{ results }}</p>
<p>{{ result }}</p>
</div>
<script>
import axios from 'axios';
export default {
name: 'search',
data () {
return {
query '',
results: '',
result: ''
}
},
methods: {
getResults(query) {
axios.get('https://apiexample.com/api/search.php?t_id=' + query).then( response => {
this.results = response.data.items;
this.result = response.data.items[0]['1:B'];
});
}
}
}
So for this.results I get something similar to
[{"1:A":10,"1:B":20,"1:C":30,"1:D":40,"1:E":50},
{"1:A":20,"1:B":30,"1:C":40,"1:D":50,"1:E":60},
{"1:A":30,"1:B":40,"1:C":50,"1:D":60,"1:E":70},
{"1:A":40,"1:B":50,"1:C":60,"1:D":70,"1:E":80}]
For this.result I am getting undefined when I am trying to get the value of 20. Probably navigating that type of response incorrectly or perhaps something more specific needs to be added to data() {}?
Any help would be appreciated.
Thanks.

As noted in the comments, response.data.items is a string, not an object. This seems like a flawed API response, with the items unnecessarily encoded as a JSON string within the response.
However, assuming that fixing the problem in the server is not possible, the items can be decoded in the UI:
this.results = JSON.parse(response.data.items);
this.result = this.results[0]['1:B'];

Related

Vue 3 how to send parameters as json to axios get

I have an api which I'm supposed to send a specific id as parameters to, so that it returns data based on the filtered list.
I tried to send it as :
await this.$store.dispatch("axiosGet",
{url: 'folder/api/property-walls'}, {propertyEid: this.id}).then(response => {
if (response.status === 'error') return
this.wallList = response.data.data.data
})
but it doesn't make any differences.
my API recieves sth like this.
can anyone help me out with the solution?
you can use params in your get requst
this will work!
axios.get('/api', {
params: {
foo: 'bar'
}
});
from this refrence
Axios get in url works but with second parameter as object it doesn't

Angular: How to get async data for template

I have the following problem:
I want to make a table with entries (Obj). And some of them have a file attribute.
If they have a file attribute (entry.file) I want to make a backend call to get the url of that file:
public getFileURL(archiveID: string, documentID: string, sysID: string){
const request: FileRequest = {
archiveID: archiveID,
documentID: documentID,
sysID: sysID
};
this.fileService.file(request).subscribe(response => {
if (response) {
return response;
}
})
}
This is called like: getFileURL(entry.file.archiveID, entry.file.documentID, entry.file.sysID)
And it should return an Observable, so I can check if i got a backend response.
<tr *ngFor="let entry of period.claims; let i = index">
...
<td>
<div *ngIf="entry.file">
<div *ngIf="fileClientService.getFileURL(entry.file.archiveID, entry.file.documentID, entry.file.sysID) | async as file; else loading">
<a target="about:blank" class="download" (click)="clickLink(file)"></a>
</div>
<ng-template #loading let-file>loading..</ng-template>
</div>
</td>
All I want is to display "loading" until the url is loaded and then display the a-tag.
Also, the url parameter coming back from the backend could be empty. So i also need to display nothing if the url is empty ("").
At the moment it fires hundred of backend calls for 2 objects with the entry.file property :(
I am not that good with Observables and I hope someone can help me with that.
Thank you so far :)
You need to return Observable directly from your method and map your period.claims into one Observable:
// add proper type
entries: Observable<...> = getEntries();
getEntries() {
// we map every claim to Observable returned from getFileURL method
const entries = period.claims.map(entry =>
getFileURL(...).pipe(
// we use map to return whole entry from Observable - not only url
map(url => ({
...entry,
url,
}))
));
// forkJoin will return one Observable with value array when each Observable is completed
return forkJoin(...entries);
}
public getFileURL(archiveID: string, documentID: string, sysID: string): Observable<...> {
const request: FileRequest = {
archiveID: archiveID,
documentID: documentID,
sysID: sysID
};
return this.fileService.file(request).pipe(filter(Boolean));
}
If you want not to pass to template empty response you could use filter operator and pass Boolean as callback. It will return only truthy values. You can read more about it: https://www.learnrxjs.io/learn-rxjs/operators/filtering/filter
You can read also more about forkJoin: https://www.learnrxjs.io/learn-rxjs/operators/combination/forkjoin
Note that adding proper type to method would tell you what you're doing wrong ;)

React constant with parameters using square brackets

I'm new to React.
I have the code below with a function, but when I run it, it returns an error:
TypeError: renderJson[item.node] is not a function.
How can I fix the renderJson function?
export const readItem = item => {
printlog(item);
return renderJson[item.node](item);
};
const renderJson = {
"heading": item => <h1>{item.map(item => readItem(item))}</h1>
};
If you're trying to create a single React functional component that takes a JSON, and outputs the items in the JSON as a header, it would be more like this:
// If you're getting this JSON from an external source using something like a GET request, put the request inside a "useEffect()" hook
const myJson = {
"heading": ["My First Header", "My Second Header"]
};
export const Header = () => {
console.log(myJson);
return <h1>{myJson.heading.map(header => header}</h1>
};
I apologize if this is a misinterpretation of your question. If it is, any additional details would be helpful.

How to count number of elements in a JSON result with react js

i tried to get the length of my Json response but it doesn't work
i used "length" with my json result
this is what i tried in my class in react js :
componentDidMount() {
axios.get(`http://localhost:51492/api/CommentSurExperience/GetAllCommentOfExperience/${this.props.passedVal}`)
.then(res => {
const persons = res.data;
const longeur = res.length;
this.setState({ persons, longeur });
})
}
then i returned this :
<div> <p> { this.state.longeur}</p> </div>
but i got an empty result .
how can i count how many elements in my JSON response , please
thank you for your help.
**********update***********
this is my JSON result using postman
and this is a capture showing what console.log(res) shows
it should be
const longeur = res.data.length;
You need to use res.data.length. You can see the response schema in Axios docs.
You have to specify which key in your state that number belongs to:
setState({
persons: res.data,
longeur: longeur
})
Else it might be because it's res.data.length that you want?

How to efficiently fetch data from URL and read it with reactjs?

I have some URL with json and need to read data.
For the sake of this example json looks like this:
{
"results": [
...
],
"info": {
...
}
}
I want to return fetched data as a property of a component.
What is the best way to do it?
I tried to do that with axios. I managed to fetch data, but after setState in render() method I received an empty object. This is the code:
export default class MainPage extends React.Component {
constructor(props: any) {
super(props);
this.state = {
list: {},
};
}
public componentWillMount() {
axios.get(someURL)
.then( (response) => {
this.setState({list: response.data});
})
.catch( (error) => {
console.log("FAILED", error);
});
}
public render(): JSX.Element {
const {list}: any = this.state;
const data: IScheduler = list;
console.log(data); // empty state object
return (
<div className="main-page-container">
<MyTable data={data}/> // cannot return data
</div>
);
}
}
I don't have a clue why in render() method the data has gone. If I put
console.log(response.data);
in .then section, I get the data with status 200.
So I ask now if there is the other way to do that.
I would be grateful for any help.
----Updated----
In MyTable component I got an error after this:
const flightIndex: number
= data.results.findIndex((f) => f.name === result);
Error is:
Uncaught TypeError: Cannot read property 'findIndex' of undefined
What's wrong here? How to tell react this is not a property?
Before the request is returned, React will try to render your component. Then once the request is completed and the data is returned, react will re-render your component following the setState call.
The problem is that your code does not account for an empty/undefined data object. Just add a check, i.e.
if (data && data.results) {
data.results.findIndex(...);
} else {
// display some loading message
}
In React, after you have stored your ajax result in the state of the component (which you do appear to be doing), you can retrieve that result by calling this.state.list
So to make sure this is working properly, try <MyTable data={this.state.list}>
https://daveceddia.com/ajax-requests-in-react/