Optional Chaining For JSON API Call Not Working In React - javascript

So I am making a GET call in React using the fetch library. This is the schema:
{
"originatingRequest": {
"clientId": 1,
"simulationName": "Season 2020",
"teamRatings": [{
"teamId": 1,
"rating": 2.5
},
{
"teamId": 2,
"rating": 0.85
},
{
"teamId": 3,
"rating": 1.35
},
{
"teamId": 4,
"rating": 1.35
}
],
"simulationId": "7d49cb14-d99e-4315-bba3-077d114ab6fc"
},
"markets": [{
"name": "Winner",
"selections": [{
"name": "Manchester City",
"probability": "0.25"
},
{
"name": "Manchester United",
"probability": "0.25"
},
{
"name": "Liverpool",
"probability": "0.25"
},
{
"name": "Chelsea",
"probability": "0.25"
}
]
},
{
"name": "Top Two",
"selections": [{
"name": "Manchester City",
"probability": "0.95"
},
{
"name": "Manchester United",
"probability": "0.05"
},
{
"name": "Liverpool",
"probability": "0.95"
},
{
"name": "Chelsea",
"probability": "0.05"
}
]
}
],
"created": "2020-05-27T11:12:43.467644"
}
I'm interested in the markets array, and want the probabilities returned for the Winner market in a Table. This component is rendered off a redirect, hence the useLocation() to get the parameter Id.
I got directed to optional chaining the other day, so I do some checking to see if there are any values in the object, if not return null. Even though the console.log() returns an object, it seems the final table is null:
function SimulationReport(props) {
const location = useLocation();
const [simResult, setSimResult] = useState(
getSimById(location.state.simId)
);
return (
<GridWrapper>
<div>
<TableWrapper>
<Table striped bordered hover size="sm" responsive>
<thead>
<tr className="same-col-widths">
<th>Team Name</th>
<th>Win Probability</th>
</tr>
</thead>
<tbody>
{simResult?.markets?.length
? simResult.markets
.find(t => t.name === "Winner")
.selections.map(selection => (
<tr key="">
<td>{selection.name}</td>
<td>{selection.probability}</td>
</tr>
))
: null}
</tbody>
</Table>
</TableWrapper>
</div>
</GridWrapper>
);
}
export default SimulationReport;
This is the call to the API that has been exposed:
export function getSimById(simId) {
return fetch(simsUrl + "/results/" + simId, {
method: "GET"
})
.then(handleResponse)
.catch(handleError);
}
And the response handling:
export async function handleResponse(response) {
if (response.ok) {
let someResponse = response.json();
console.log("loading response");
console.log(someResponse);
return someResponse;
}
if (response.status === 400) {
// So, a server-side validation error occurred.
// Server side validation returns a string error message, so parse as text instead of json.
throw new Error(error);
}
const error = await response.text();
console.log("error was: " + error);
console.log("status was: " + response.status);
throw new Error("Network response was not ok.");
}
// In a real app, would likely call an error logging service.
export function handleError(error) {
// eslint-disable-next-line no-console
console.error("API call failed. " + error);
throw error;
}
How do I populate the final rendered Table with the Winner market probabilities?

Related

json API response code using flatmap not working javascript

Problem
I’m trying to return only the objects that don’t contain any of the names on the filteredEmployers list, against the employer attribute, from an API I'm retrieving the data from.
What I've tried
I have an alternative piece of code that seems to work fine when I don’t connect to the API (i.e. reading from hardcoded data), but when I connect to the API, even though I get the following response (when immediately logged after retrieval), the code then doesn’t execute…
{
"Pagination": {
"NumberOfPeople": 185,
"PageSize": 200,
"PageNumber": 1,
"NumberOfPages": 1
},
"People": [
{
"name": "TJ",
"job": "Software Engineer",
"organization": {
"company": {
"employer": "amazon",
"department": "IT"
}
},
"location": {
"city": "Boston",
"state": "Massachusetts"
}
},
{
"name": "Dominique",
"job": "CEO",
"organization": {
"company": {
"employer": "IBM",
"department": "IT"
}
},
"city": "Seattle",
"state": "Washington"
},
{
"name": "Enrique",
"job": "Engineer",
"organization": {
"company": {
"employer": "Bellkrieg Megasystems",
"department": "Construction"
}
},
"location": {
"address": {
"state": "New York",
"city": "New York City",
"zip": "11323"
}
}
},
{
"name": "Bob",
"job": "Project Manager",
"organization": {
"company": {
"employer": "Megasystems",
"department": "R&D"
}
},
"address": {
"location": {
"quadrant": {
"block": 1,
"state": "Texas",
"city": "Austin"
}
}
}
}
]
}
The code I’m trying to implement is here:
// constants and variables are defined here, including API credentials and the filteredEmployers array
//FYI const filteredEmployers = ['Megasystems', 'Bellkrieg'];
//the code then fetches the API data is here
.then((response) => {
return response.json();
})
.then((json) => {
//console.log(typeof json);
//console.log(json);
const people = Array.from(json).flatMap(o => o.People);
return people.filter(person => {
const employer = person?.organization?.company?.employer;
if (typeof employer !== 'string') return true;
const employerIsNotFiltered = filteredEmployers.every(
str => !employer.includes(str)
);
console.log("This is the outputted data: " + employerIsNotFiltered);
return employerIsNotFiltered;
});
})
The desired response is:
[
{
name: 'TJ',
job: 'Software Engineer',
organization: { company: [Object] },
location: { city: 'Boston', state: 'Massachusetts' }
},
{
name: 'Dominique',
job: 'CEO',
organization: { company: [Object] },
city: 'Seattle',
state: 'Washington'
}
]
Any recommendations on how to get this to execute, or alternatives to this method appreciated.
Thanks in advance
Reiterating my comment on your question: You just need to change the line
const people = Array.from(json).flatMap(o => o.People);
to
const people = json.People;
The JSON response that you included in the question is an object, and Response.json() returns a promise which resolves to an already parsed representation of the JSON text response, so in order to access the array at the People property, you only need json.People. Here is a runnable snippet based on the code and data that you showed:
// The JSON data, copied and pasted from the first code block of your question:
const json = `{"Pagination":{"NumberOfPeople":185,"PageSize":200,"PageNumber":1,"NumberOfPages":1},"People":[{"name":"TJ","job":"Software Engineer","organization":{"company":{"employer":"amazon","department":"IT"}},"location":{"city":"Boston","state":"Massachusetts"}},{"name":"Dominique","job":"CEO","organization":{"company":{"employer":"IBM","department":"IT"}},"city":"Seattle","state":"Washington"},{"name":"Enrique","job":"Engineer","organization":{"company":{"employer":"Bellkrieg Megasystems","department":"Construction"}},"location":{"address":{"state":"New York","city":"New York City","zip":"11323"}}},{"name":"Bob","job":"Project Manager","organization":{"company":{"employer":"Megasystems","department":"R&D"}},"address":{"location":{"quadrant":{"block":1,"state":"Texas","city":"Austin"}}}}]}`;
function mockFetch () {
return Promise.resolve({
json: () => Promise.resolve(JSON.parse(json)),
});
}
const filteredEmployers = ['Megasystems', 'Bellkrieg'];
mockFetch()
.then(response => response.json())
.then(json => {
// Change this line:
// const people = Array.from(json).flatMap(o => o.People);
// To:
const people = json.People;
return people.filter(person => {
const employer = person?.organization?.company?.employer;
if (typeof employer !== 'string') return true;
const employerIsNotFiltered = filteredEmployers.every(
str => !employer.includes(str)
);
return employerIsNotFiltered;
});
})
.then(console.log);

I am getting this error: uncaught (in promise) TypeError: userData.filter is not a function

I am getting this error: uncaught (in promise) TypeError: userData.filter is not a function. I have a table with data and this data has different columns or properties. I store this object array data in my vuex store and get it from my component and filter it through my component
<tr v-for="report in filteredReports" :key="report.id">
<td></td>
<td>
<div v-show="report.edit !== 'serialNum'">
<label #dblclick="report.edit = 'serialNum'">
#{{ report.serialNum }}
</label>
</div>
<input
name="serialNum"
v-show="report.edit == 'serialNum'"
v-model="serialNum"
v-on:blur="report.edit = ''"
#keyup.enter="report.edit = ''"
/>
</td>
<td>
<div v-show="report.edit !== 'reporter'">
<label #dblclick="report.edit = 'reporter'">
#{{ report.reporter }}
</label>
</div>
<input
name="reporter"
v-show="report.edit == 'reporter'"
v-model="report.reporter"
v-on:blur="report.edit = ''"
#keyup.enter="report.edit = ''"
/>
</td>
<td>
<div v-show="report.edit !== 'location'">
<label #dblclick="report.edit = 'location'">
#{{ report.location }}
</label>
</div>
<input
name="location"
v-show="report.edit == 'location'"
v-model="report.location"
v-on:blur="report.edit = ''"
#keyup.enter="report.edit = ''"
/>
</td>
This is my script for my component
<script>
export default {
name: "ReportComponent",
data() {
return {
editMode: false,
editedUser: null,
searchId: "",
searchSerial: "",
searchName: "",
searchLocation: "",
searchStatus: "",
searchComptyp: "",
searchDate: "",
userData: null,
};
},
computed: {
serialNum: {
get() {
console.log(this.$store.getters["getReport"]("5CDN098767"));
return this.$store.getters["getReport"]("5CDN098767");
},
set(value) {
this.$store.commit("updateMessage", value);
},
},
filteredReports() {
let userData = this.$store.state.reports.reports;
console.log("user", userData);
console.log("searchName", this.searchName);
return userData
.filter((report) => !report.serialNum.indexOf(this.searchSerial))
.filter((report) => !report.reporter.indexOf(this.searchName))
.filter((report) => !report.status.indexOf(this.searchStatus));
},
},
created() {
this.$store.dispatch("fetchReports");
},
methods: {
saveData() {},
},
};
</script>
As You can see in my component I am using getters and setters for two way computed binding and this is causing the error. At first I thought my filtering code was causing the problem so I had this code instead:
let userData = this.$store.state.reports.reports;
console.log("user", userData);
console.log("searchName", this.searchName);
return this.filterProductsBySerial(
this.filterProductsByName(this.filterProductsByCategory(userData))
);
},
},
created() {
this.$store.dispatch("fetchReports");
},
methods: {
filterProductsBySerial(reports) {
return reports.filter(
(report) => !report.serialNum.indexOf(this.searchSerial)
);
},
filterProductsByName(reports) {
return reports.filter(
(report) => !report.reporter.indexOf(this.searchName)
);
},
filterProductsByCategory(reports) {
return reports.filter(
(report) => !report.status.indexOf(this.searchStatus)
);
},
No success. I figured that the problem was in my store that either I needed to filter in my store or that need to update my updateMessage mutation
export default {
state: {
strict: true,
reports: [],
newArr:[]
},
getters: {
getReport: (state) => (serialNum) => {
console.log(state.reports)
return state.reports.find(x => x.serialNum === serialNum)
},
reported: (state) => state.reports,
// getQuoteById: (state) => (id) => {
// console.log(state.quotes)
// return state.quotes.find(quote => quote.id === id)
// },
},
actions: {
async fetchReports({ commit }) {
const response = await axios.get(
'http://localhost:3000/reported'
);
commit('setReports', response.data);
},
},
mutations: {
setReports: (state, payload) => (state.reports = payload),
updateMessage: (state, payload) => (state.reports = payload)
},
}
So I changed my updateMessage to this updateMessage: (state) => (serialNum) => { console.log(state.reports) return state.reports.find(x => x.serialNum === serialNum) },
But this did not give any functionality also this would only filter out the array with the given serialNum and really update it. I also tried to change my getter and as you see in my code my getter filters out based on serialNum. I have done more tries and changes but I can not write it all out here.
Json object array before adding it to an array in my store
"reported": [
{
"id": 1,
"serialNum": "5CDN098767",
"reporter": "James Hardy",
"location": "malmo",
"damage": "This is broken down",
"status": "In repair",
"priority": "5",
"date": "date",
" edit": null
},
{
"id": 2,
"serialNum": "5CDN098BHBD",
"reporter": "James Hardy",
"location": "malmo",
"damage": "This is broken down",
"status": "In repair",
"priority": "5",
"date": "date",
" edit": null
},
{
"id": 3,
"serialNum": "PX09CTY",
"reporter": "James Hardy",
"location": "malmo",
"damage": "This is broken down",
"status": "In repair",
"priority": "5",
"date": "date",
" edit": null
},
{
"id": 4,
"serialNum": "WC1309NY",
"reporter": "James Hardy",
"location": "malmo",
"damage": "This is broken down",
"status": "In repair",
"priority": "5",
"date": "date",
" edit": null
},

How to parse FractalTransformer with normalizr

I'm trying to use paularmstrong/normalizr on JSON that comes from FractalTransformer and whose nested childs have "data" attribute. Example of JSON:
{
"data": {
"object": "Offer",
"id": "5g6aqocew4qjzl40",
"real_id": 26,
"name": "Random Name",
"created_at": {
"date": "2019-06-18 11:13:08.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"readable_created_at": "1 year ago",
"site": {
"data": {
"object": "Site",
"id": "65zody8vj29vlegd",
"name": "Test Site",
"real_id": 1
}
},
"countries": {
"data": [
{
"object": "Country",
"code": "US",
"name": "United States"
},
{
"object": "Country",
"code": "DE",
"name": "Germany"
}
]
}
},
"meta": {
"include": [
"site",
"countries"
],
"custom": []
}
}
Schemas I use:
export const offerSchema = new schema.Entity('offers')
export const siteSchema = new schema.Entity('sites', {}, {
processStrategy: (value) => {
return { ...value.data }
},
idAttribute: (value) => {
return value.data.id
},
})
export const countrySchema = new schema.Entity('countries')
offerSchema.define({
site: siteSchema,
countries: [countrySchema],
})
Now the issue is that I remove 'data' from the site since it's just one object successfully, but I can't do it in the country case. Whatever I tried with custom processStrategy fails, as country is object that has data which is array (I assume this is where the issue is, going from Entity to Array). And in idAttribute function I always get complete array so can't determine the ID of single entry. So the end result is that the ID of countries is undefined. Any ides?
I actually managed with another approach. I added processStrategy on the parent, 'Offer' in this case, so all 'data' parts get stripped before they reach other child schemas.
const normalizrStripDataOptions = {
processStrategy: (value) => {
const ret = { ...value }
Object.keys(ret).forEach((key) => {
if (ret[key] !== null) {
if (ret[key].data && Array.isArray(ret[key].data)) {
ret[key] = [...ret[key].data]
}
if (ret[key].data && typeof ret[key].data === 'object') {
ret[key] = { ...ret[key].data }
}
}
})
return ret
},
}
export const offerSchema = new schema.Entity('offers', {}, normalizrStripDataOptions)
export const siteSchema = new schema.Entity('sites')
export const countrySchema = new schema.Entity('countries')
offerSchema.define({
site: siteSchema,
countries: [countrySchema],
})

How to fetch particular documents in elasticsearch index

I want to fetch all the data of the corresponding particular field, and have a response of the elastic search.
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 35,
"relation": "eq"
},
"max_score": 0.44183275,
"hits": [
{
"_index": "allevents",
"_type": "_doc",
"_id": "jQPDaG0BcOh3oggcguoV",
"_score": 0.44183275,
"_source": {
"category": "sessions",
"contentid": "KqRLj2lWZ3",
"clientname": "omkarpathlab",
------------------
}]
I tried search function it returning an error.
var elasticsearch = require('elasticsearch');
var client = new elasticsearch.Client({
host: 'aaa',
log: 'trace',
apiVersion: '7.1'
});
client.search({
"size": 20,
"query": {
"query_string": {
"default_field": "clientname",
"query": "omkarlab"
}
}
}).then((res) => {
console.log("resultData", res);
}, (err) => {
console.log("err", err);
});
enter code here
Error showing:
{ Error: [illegal_argument_exception] request [/_search] contains unrecognized parameter: [query]
Please suggest me how to solve this kind of problem.
You should specify your field under default_field, not the value you are looking for. The field you are trying to query is clientname in your case, and the value you are looking for is omkarpathlab. So your query should be as follows:
"query": {
"query_string": {
"default_field": "clientname",
"query": "omkarpathlab"
}
}
edit. But your query inside of the body property:
client.search({
"size": 20,
"body": {
"query": {
"query_string": {
"default_field": "clientname",
"query": "omkarlab"
}
}
}
}).then((res) => {
console.log("resultData", res);
}, (err) => {
console.log("err", err);
});
You can use below code to connect to elasticsearch. I have tested it on 5.6 version
'use strict'
const { Client } = require('#elastic/elasticsearch')
const client = new Client({ node: 'http://XXX:9200' })
async function run () {
// Let's search!
const { body } = await client.search({
index: 'XXX',
type : 'XXX',
body: {
query: {
match_all: {}
}
}
})
console.log(body.hits.hits)
}
run().catch(console.log)
Code is a sample from https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/search_examples.html site.
for search documentation check below link
https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/api-reference.html#_search

How do I access the value of a json Array with react-apollo?

The json data is a mixture of array and object.
The object is well accessible.
How do I access each of these data in an array?
I think I can use map, but I get an error.
I don't know how to pass values ​​using the map method.
Please Help.
<Query query={USER_QUERY}>
{
({loading, error, data }) => {
if (error) return 'error';
if (loading) return 'loading';
return (data.getUsers.history.dateInformation.map(data => (
<Fragment>
<p>User adid: </p>
{data.monthly.month}
</Fragment>)
));
}
}
</Query>
This is gql.
export const USER_QUERY = gql`
query{
getUsers{
gender
age
job
location {
dailyMovingAverage
home
mostStayingArea
office
}
history {
dateInformation {
monthly {
month
favorateTransitionService
movingCarRate
}
daily {
date
movingCarRate
}
}
}
}
}
This is json data.
{
"data": {
"getUsers": [
{
"gender": "F",
"age": "26",
"job": "student",
"location": {
"dailyMovingAverage": 3,
"home": "aaa",
"mostStayingArea": "aaaa",
"office": "aaa"
},
"history": {
"dateInformation": [
{
"monthly": [
{
"month": "March",
"favorateTransitionService": "Car",
"movingCarRate": 0,
...

Categories

Resources