Filtering Axios response - javascript

I'm trying to filter an axios response. My latest attempt the filter appears to be working, but my components aren't getting the expected data, only the correct # of records.
methods: {
loadItems() {
// Init variables
var self = this
var app_id = "ID";
var app_key = "KEY";
this.items = []
axios.get(
"https://api.airtable.com/v0/"+app_id+"/Pages",
{
headers: { Authorization: "Bearer "+app_key }
}
).then(function(response){
self.items = response.data.records.filter(item => item.fields.fxPage == 'TestPage');
response.data.records.map((item)=>{
return {
id: item.id,
...item.fields
}
})
}).catch(function(error){
console.log(error)
})
}
}

So close!
the .map() method returns a NEW array, so the map in that case is just returning and not getting used anywhere (e.g saving to a variable), what I would do would be to attach the map after the filter. e.g
self.items = response.data.record.filter(item => item.fields.fxPage === "TestPage").map(item => {
return {
id: item.id,
...item.fields
}
})
I hope this helps!

Related

Why can't I access this variable from the state VUEX 4

I of course tried it with out the state.groupCrud.group and still no go. Is my syntax correct. I am using vuejs3 i will provide some screenshots of the object.
This is the State Object:
const state = () => ({
group: {}, //This is the one i am trying to access.
groups: [],
loading: false,
error: null,
success: false,
});
I am getting the data from api like this:
async getGroup({ commit }, id) {
try {
await commit('axiosSingleDataBegin');
const query = await DataService.get(`/groups/unique/${id}`);
await commit('axiosSingleDataSuccess', query.data.data.group);
} catch (err) {
await commit('axiosSingleDataErr', err);
}
},
And I am setting it to the state like this:
axiosSingleDataSuccess(state, data) {
state.loading = false;
state.group = data;
},
This is how i am using the state
setup() {
const { state, dispatch } = useStore();
const group = state.groupCrud.group;
const { params } = useRoute();
onMounted(() => {
dispatch('getGroup', params.id);
console.log(group); //doesnt work
});
// ...
},
This is the console.log(state.groupCrud); Object
This is the console.log(state.groupCrud.group) Object
I am getting a empty Proxy object when i try to use the state.groupCrud.group although the object is not empty

Javascript Class set private var on public function

can i set variables on the scope of the class to be used later?
example
class TestClass {
#key = '';
#reference = '';
#onReturn = () => {};
constructor({ key } = {}) {
this.#key = key || this.#key;
this.#onReturn = onReturn || this.#onReturn;
}
login(username, password) {
this.#submit(username, password);
};
#submit(username, password) {
fetch(
`/login/${this.#key}`,
)
.then(response => response.json())
.then((json) => {
this.#handleResponse(json);
})
};
#handleResponse(json) {
this.#reference = json.reference;
this.#onReturn();
};
token() {
console.log(this.#key, this.#reference); // "blabla", empty
};
};
const Test = new TestClass({ // initializing the class
key: 'blabla',
onReturn: tokenSubmit
});
const onLoginSubmit = () => {
Test.login(username, password); // running a fetch which will set a private var
};
const tokenSubmit = () => {
Test.token(); // private var returns empty
};
which has two public methods login and token
where the token should log the key and the reference
as a result i do get the key which was set on the constructor
but the reference which was set while handling a fetch returns empty
Following up on #vlaz's comment, try the following test code:
async function test() {
const Test = new TestClass({ key: 'blabla' }); // initializing the
class
await LoginModule.login({ username, password }); // running a fetch which will set a private var
LoginModule.token(); // private var returns empty
}
The addition of await waits for the fetch to complete before proceeding to the next line, calling LoginModule.token().
For this to work, you'll also need to modify #submit to return fetch's promise:
#submit({ username, password }) {
return fetch(
`/login/${this.#key}`,
)
.then(response => response.json())
.then((json) => {
this.#handleResponse({ json });
})
};

Trying to access state in oncompleted method

I have API query and getting the result and setting those in a state variable in Oncompleted method of API query, Now i am updating the same state variable in another api query "onCompleted method.
I am not able to access the result from state what i have set before in first api query and below is my code
Query 1:
const designHubQueryOnCompleted = designHubProject => {
if (designHubProject) {
const {
name,
spaceTypes
} = designHubProject;
updateState(draft => { // setting state here
draft.projectName = name;
draft.spaceTypes = (spaceTypes || []).map(po => {
const obj = getTargetObject(po);
return {
id: po.id,
name: obj.name,
category: obj.librarySpaceTypeCategory?.name,
description: obj.description,
warning: null // trying to modify this variable result in another query
};
});
});
}
};
const { projectDataLoading, projectDataError } = useProjectDataQuery(
projectNumber,
DESIGNHUB_PROJECT_SPACE_TYPES_MIN,
({ designHubProjects }) => designHubQueryOnCompleted(designHubProjects[0])
);
Query 2:
const {
// data: designhubProjectSpaceTypeWarnings,
loading: designhubProjectSpaceTypeWarningsLoading,
error: designhubProjectSpaceTypeWarningsError
} = useQuery(DESIGNHUB_PROJECT_LINKED_SPACETYPE_WARNINGS, {
variables: {
where: {
projectNumber: { eq: projectNumber }
}
},
onCompleted: data => {
const projectSpaceTypeWarnings = data.designHubProjectLinkedSpaceTypeWarnings[0];
const warnings = projectSpaceTypeWarnings.spaceTypeWarnings.reduce((acc, item) => {
const spaceTypeIdWithWarningState = {
spaceTypeId: item.spaceTypeProjectObjectId,
isInWarningState: item.isInWarningState
};
acc.push(spaceTypeIdWithWarningState);
return acc;
}, []);
console.log(state.spaceTypes); // trying to access the state here but getting empty array
if (state.spaceTypes.length > 0) {
const updatedSpaceTypes = state.spaceTypes;
updatedSpaceTypes.forEach(item => {
const spaceTypeWarning = { ...item };
spaceTypeWarning.warning = warnings?.filter(
w => w.spaceTypeId === spaceTypeWarning.id
).isInWarningState;
return spaceTypeWarning;
});
updateState(draft => {
draft.spaceTypes = updatedSpaceTypes;
});
}
}
});
Could any one please let me know where I am doing wrong with above code Or any other approach to modify the state, Many thanks in advance!!

JSON.stringify() losing nested properties I know the cause but don't know the answer

I have 2 objects:
const subscription = {
endpoint: "dfksjfklsjkld",
keys: {
pkey: "dfsfsdfsf",
auth: "dfsdfsdfsd"
}
};
const extra = {
email: "dfsdfs",
ip:"231342.342.342.34"
};
I would like to put the extra object inside subscription, so it looks like:
subsciption = {
endpoint: ......
keys: {...},
extra: {
email:....,
ip: .....
}
}
then I need to send it as body of a http request:
const response = await fetch(url, {
method: "PUT",
mode: "no-cors",
cache: "no-cache",
credentials: "same-origin",
headers: {
"Content-Type": "application/json",
},
redirect: "follow",
referrerPolicy: "no-referrer",
body: JSON.stringify(subscription),
});
but I found no matter what I do, I always lose the extra property inside subscription in the process of JSON.stringify().
I know the cause: it's because that the properties in extra object are not enumerable.
So far, I have tried:
1.use the spread:
newSub = {
...subscription,
...extra
}
but the content of newSub will be exactly same with extra, the properties of subscription are all lost.
2.add toJSON function into the place where I generate the extra object
getExtra() : {
.......
return {
city: ipObject.city,
country: ipObject.country_name,
ip: ipObject.ip,
lat: ipObject.latitude,
lng: ipObject.longitude,
org: ipObject.org,
postal: ipObject.postal,
region: ipObject.region,
toJSON: () => {
return this;
}
};
}
no effect at all.
I attach my code here:
async function updateSubscription() {
try {
const allowed = await askForPermission();
if (!allowed) return;
let subscription = await getSubscription();
if (!subscription) return;
// email
const email = getEmail();
if (!email || !validateEmail(email)) {
alert("huh...so how are you going to receive notifications?");
return;
}
// ip
let ipObject = await getIP();
let extra = {};
if (ipObject) {
ipObject.email = email;
extra = ipObject;
} else {
extra.email = email;
}
console.log("extra: ", extra);
// var newSubscription = Object.assign({}, subscription, {extra});
// const newSubscription = {
// ...subscription,
// extra
// };
let newSubscription = subscription;
newSubscription["extra"] = extra;
console.log("new subscription1: ", newSubscription);
console.log("new subscription1 stringified: ", JSON.stringify(newSubscription));
const successful = await saveRegistration(newSubscription);
if (successful) alert("you have successfully subscribed to the DC monitor");
else alert("shit happens, try it later");
} catch (err) {
console.log("updateSubscription() failed: ", err);
}
}
async function getSubscription() {
console.log("try to get subscription");
try {
const swRegistration = await navigator.serviceWorker.ready;
const pushSubscription = await swRegistration.pushManager.getSubscription();
console.log("pushSubscription: ", pushSubscription);
return pushSubscription;
} catch (error) {
console.log("getSubscription() error: ", error);
return null;
}
}
Update
1.Tried 1 more approach:
var newSubscription = Object.assign({}, subscription, {extra});
console.log("subscription: ", newSubscription);
console.log("subscription stringified: ", JSON.stringify(newSubscription));
here is the output screenshot:
2.Also this one:
const newSubscription = {
...subscription,
extra
};
console.log("new subscription: ", newSubscription);
console.log("new subscription stringified: ", JSON.stringify(newSubscription));
And here is the screenshot of output:
3.with string index approach:
let newSubscription = subscription;
newSubscription["extra"] = extra;
console.log("new subscription1: ", newSubscription);
console.log("new subscription1 stringified: ", JSON.stringify(newSubscription));
If mutating subscription is OK, you can just use:
subscription['extra'] = extra;
If you want a new object, you can use:
const subscriptionObject = Object.assign({}, subscription, { extra });
EDIT: Since you are working with the Push API, the properties in PushSubscription are not enumerable. So the subscription object does not behave quite like a normal object, which is why the suggested approaches have not been working.
However, you can serialize the push subscription using PushSubscription.toJSON() first to serialize it to a "normal" object, then use one of the suggested techniques:
subscriptionObject = Object.assign({}, subscription.toJSON(), { extra });
why don't you use like simple assignment of property
let subscription = {..}
const extra = {..}
then
subscription.extra = extra;
it should work
This is a bit hacky, but it looks like we don't know how the PushSubscription object is implemented, and it may not work as you expect...
... however it seems to convert to JSON properly using its own method (according to its API), so you may want to try something like this:
const newSub = { ...JSON.parse(subscription.toJSON()), extra };
Thus, converting it to JSON (using the toJSON method in the Push API) and back to a "normal" javascript object, -then- adding the extra property to it.
Have you tried
newSub = {
...subscription, extra
}
you don't need to spread extra in this case.
sub = JSON.stringify(newSub) should result in: "{"endpoint":"dfksjfklsjkld","keys":{"pkey":"dfsfsdfsf","auth":"dfsdfsdfsd"},"extra":{"email":"dfsdfs","ip":"231342.342.342.34"}}"

Handling multiple ajax requests, only do the last request

I'm doing a project that fetch different types of data from SWAPI API (people, planets, etc.) using react but I have an issue with multiple Ajax request.
The problem is when I quickly request from 2 different URL for example, 'species' and 'people', and my last request is 'species' but the load time of 'people' is longer, I will get 'people' instead.
What I want is to get the data of the last clicked request, if that make sense.
How do I achieve that? All the solution I found from Google is using jQuery.
Here's a slice of my code in src/app.js (root element) :
constructor(){
super();
this.state = {
searchfield: '',
data: [],
active: 'people'
}
}
componentDidMount() {
this.getData();
}
componentDidUpdate(prevProps, prevState) {
if(this.state.active !== prevState.active) {
this.getData();
}
}
getData = async function() {
console.log(this.state.active);
this.setState({ data: [] });
let resp = await fetch(`https://swapi.co/api/${this.state.active}/`);
let data = await resp.json();
let results = data.results;
if(data.next !== null) {
do {
let nextResp = await fetch(data.next);
data = await nextResp.json();
let nextResults = data.results
results.push(nextResults);
results = results.reduce(function (a, b) { return a.concat(b) }, []);
} while (data.next);
}
this.setState({ data: results});
}
categoryChange = (e) => {
this.setState({ active: e.target.getAttribute('data-category') });
}
render() {
return (
<Header searchChange={this.searchChange} categoryChange={this.categoryChange}/>
);
}
I made a gif of the problem here.
Sorry for the bad formatting, I'm writing this on my phone.
You have to store your requests somewhere and to abandon old ones by making only one request active. Something like:
getData = async function() {
console.log(this.state.active);
this.setState({ data: [] });
// my code starts here
if (this.controller) { controller.abort() }
this.controller = new AbortController();
var signal = controller.signal;
let resp = await fetch(`https://swapi.co/api/${this.state.active}/`, { signal });
let data = await resp.json();
let results = data.results;
if(data.next !== null) {
do {
let nextResp = await fetch(data.next);
data = await nextResp.json();
let nextResults = data.results
results.push(nextResults);
results = results.reduce(function (a, b) { return a.concat(b) }, []);
} while (data.next);
}
this.setState({ data: results});
}

Categories

Resources