Can not find an object dynamically from an array - javascript

I have to get the client_id from an api call which would be available in body.
const oauthClients = [
{ "0ADAA2B8": "96eb8c0fbfb31ac43288" },
{ P3CKTGC7: "FKC78N6Plm1Vwjk8KItS" },
];
const client_id = JSON.parse(JSON.stringify(req.body.client_id));
const filtered_value = oauthClients.find((ele) => {
return (ele.client_id = client_id);
});
console.log(filtered_value);
I have tried like return ${ele}+.+`${req.body.client_id}
Anyone please help..!

You need to use the strict equality operator instead
const filtered_value = oauthClients.find((ele) => {
return ele.client_id === client_id;
});
Also oauthClients us an object so you can't really traverse it using .find and access ele.client_id, you will need to somehow take the object values and traverse them in an array like fashion
e.g. using Object.keys() :
const filtered_value = Object.keys(oauthClients).find((key) => {
return oauthClients[key] === client_id;
});

What makes this a bit hard is that your original data isn't really well structured:
Given this:
const oauthClients = [
{ "0ADAA2B8": "96eb8c0fbfb31ac43288" },
{ P3CKTGC7: "FKC78N6Plm1Vwjk8KItS" },
];
There's no "client_id" field - the client ID is the field name, so its hard to parse. In Javascript, to get generic access to the keys and values of a dictionary, you use the Object.keys() and Object.values() functions.
I think you're looking to get the token given the client ID, so something like this:
/**
* Returns the token for the given client ID or undefined if it isn't found
*/
function findToken(clientId: string) {
const foundElement = oauthClients.find(e => Object.keys(e)[0] === clientId)
return foundElement
? Object.values(foundElement)[0]
: undefined
}

Related

javascript return an filtered array of objects using .map() from an api response

I have this array of data which I want to manipulate and return another array of object with only what I need, so I was thinking when I receive the api data it is possible to create an map responses like:
const [stateData, setStateData] = useState({stateData:[]});
Promise.all(promises).then(response => {
let info = [];
response.forEach(res => {
info = info.concat(res.info);
});
//and here to add my map:
const myData = info.map(fiterData,index) => {
return info [
{"id":fiterData.id},
{"name":fiterData.name},
{"name":fiterData.description}
// and so on ...
]
}
setStateData(info);
});
and afterwards to access like myData.property ?
So will work if will be used in this way ?

Updating data in an Object using Firebase arrayUnion

I am looking to update data in an object without changing the index of the object within the array it is contained. As it currently stands, the code removes the current object from the array and then applies array Union to update the array but pushes the component to the end of the array but I am looking to just update the data without the component losing its index. This is the code I am currently working with, I looked through the Firebase docs to see if there was a way to just update the component but couldn't find anything if anyone could point me in the right direction, please.
await firestore.update(project, {
pages: firestore.FieldValue.arrayRemove(page),
});
await firestore.update(project, {
pages: firestore.FieldValue.arrayUnion(newPage),
});
Unfortunately there is no field transform to replace a value like this:
firestore.FieldValue.arrayReplace(page, newPage);
Storing arrays and making changes by index in remote databases is generally discouraged. This older Firebase blog post covers some of the reasons why even though it was written with the Firebase Realtime Database in mind.
If the order of that array is important, you have two options:
fetch the array, mutate it, and then write it back. (simple)
fetch the array, find the relevant index, update that index only. (difficult)
To achieve the first result, you would make use of a transaction to find the previous value and replace it:
const db = firebase.firestore();
const projectDocRef = db.doc("projects/projectId");
function replacePage(oldPage, newPage) {
return db.runTransaction(async (t) => {
const snapshot = await t.get(projectDocRef);
if (!snapshot.exists) {
// no previous data, abort.
return "aborted";
}
const pagesArray = snapshot.get("pages");
const index = pagesArray.findIndex((page) => page === oldPage);
if (index === -1)
return "not-found";
pagesArray[index] = newPage;
await t.set(projectDocRef, { pages: pagesArray }, { merge: true });
return "replaced";
});
}
replacePage("index", "shop")
.then((result) => console.log("Page replacement was " + (result === "replaced" ? "" : " not") + " successful"))
.catch((err) => console.error('failed: ', err));
Note: Anything beyond this point is educational. There are many issues with this approach at scale.
Because Firestore doesn't support array entry replacement by index, you'll need to implement a way to update an index using something Firestore understands - maps. Using some FirestoreDataConverter trickery, you can use the converter to serialize your array as a map when you write it to Cloud Firestore and deserialize it back to an array when you read it. The major trade-off here is in how you will be able to query your data. You will be able to perform queries by index (such as where('pages.0', '==', 'shop')) but you'll lose the ability to use array-contains queries (such as where('pages', 'array-contains', 'shop')).
First, you need to define the converter:
// const obj = {};
// setNestedProperty(obj, ["a", "b", "c"], true)
// obj is now { "a": { "b": { "c": true } } }
function setNestedProperty(originalObj, pathPropsArray, val) {
const props = pathPropsArray.slice(0, -1);
const lastProp = pathPropsArray[pathPropsArray.length-1];
const parent = props.reduce((obj, p) => obj[p] ? obj[p] : (obj[p] = {}), originalObj);
parent[lastProp] = val;
}
const pagesArrayConverter = {
toFirestore(data) {
if (data.pages !== undefined) {
// step 1) convert array to map
const pagesAsMap = {};
data.pages.forEach((page, index) => {
if (page !== undefined) {
pagesAsMap[index] = page;
}
});
data.pages = pagesAsMap;
// step 2) if there are any mutations to "pages"
// while you are changing it, make the
// changes now before uploading to Firestore
Object.keys(data)
.filter(k => k.startsWith("pages."))
.forEach(k => {
const nestedValue = data[k];
data[k] = undefined;
delete data[k];
setNestedProperty(pagesAsMap, k.slice(6).split("."), nestedValue);
});
}
return data;
},
fromFirestore(snapshot, options) {
const data = snapshot.data(options);
if (data.pages !== undefined) {
const pagesAsArray = [];
Object.entries(data.pages)
.map(([index, page]) => pagesAsArray[index] = page);
// `pagesAsArray` may have empty elements, so we need
// to fill in the gaps with `undefined`:
data.pages = Array.from(pagesAsArray);
}
return data;
}
};
Which you would then attach to a query/reference like this:
const db = firebase.firestore();
const projectDocRef = db.doc("projects/projectId")
.withConverter(pagesArrayConverter)
If you already know that the previous value has an index of 2, you can just use:
await projectDocRef.set({ "pages.2": newPage }, { merge: true });
If you need to find it like before, you can use a transaction:
function replacePage(oldPage, newPage) {
return db.runTransaction(aysnc (t) => {
const snapshot = await t.get(projectDocRef);
if (!snapshot.exists) {
// no previous data, abort.
return "missing";
}
const data = snapshot.data();
// data is a { pages: Page[] }
const index = data.pages.findIndex((page) => page === oldPage);
if (index === -1)
return "not-found";
await t.set(projectDocRef, { ["pages." + oldIndex]: newPage }, { merge: true });
return "replaced";
});
}
replacePage("index", "shop")
.then((result) => console.log("Page replacement was " + (result === "replaced" ? "" : " not") + " successful"))
.catch((err) => console.error('failed: ', err));
arrayUnion adds new items to the array and arrayRemove removes items from an array. There isn't any way to update an existing item in array directly.
You would have to fetch the document, manually add/update the item at relevant index and then update the whole array back to the document.

How to implement forEach() in JSX - React Native for Custom Headers

I am trying to create a method that returns a JSON object for custom headers to use with HTTPS requests. This should be defined as customHeaders={{headerKey: 'headerValue'}}
I am new to JSX and a little confused with my implementation of forEach loop here.
Here, this.props.httpHeaders passes a list of Keys and Values. The key is this.props.headerKey and corresponding value this.props.headerValue
The expected return is an Object that holds the key value pairs as {headerKey: 'headerValue'}
Here's my not so correct implementation. Can anyone explain me how to implement forEach() here? Thanks
getCustomHeaders = () => {
var customHeaders;
let keyValueStr = "";
if (this.isStatusAvailable(this.props.httpHeader) && this.isStatusAvailable(this.props.restURL)) {
// Building Custom Headers input string
this.props.httpHeader?.items?.forEach((element) => {
const attrKey = this.props.headerKey.get(element);
const attrValue = this.props.headerValue.get(element);
if (keyValueStr !== "") {
keyValueStr = keyValueStr.concat(",");
}
keyValueStr = keyValueStr+attrKey.value+": "+"'"+attrValue.value+"'";
});
}
customHeaders = JSON.parse("{" + keyValueStr + "}");
return customHeaders;
};

Draft.js. How to get all entities data from the ContentState

From official docs I know about 2 methods: get entity by its key and get last created entity. In my case, I also need a method to access all entities from current ContentState.
Is there any method that could perform this? If not, is there a one that can provide all entities keys?
const getEntities = (editorState, entityType = null) => {
const content = editorState.getCurrentContent();
const entities = [];
content.getBlocksAsArray().forEach((block) => {
let selectedEntity = null;
block.findEntityRanges(
(character) => {
if (character.getEntity() !== null) {
const entity = content.getEntity(character.getEntity());
if (!entityType || (entityType && entity.getType() === entityType)) {
selectedEntity = {
entityKey: character.getEntity(),
blockKey: block.getKey(),
entity: content.getEntity(character.getEntity()),
};
return true;
}
}
return false;
},
(start, end) => {
entities.push({...selectedEntity, start, end});
});
});
return entities;
};
How I get the all entities keys:
const contentState = editorState.getCurrentContent()
const entityKeys = Object.keys(convertToRaw(contentState).entityMap)
result:
[0, 1]
then you can call the getEntity(key) method to get the responding entity.
this is how convertToRaw(contentState) looks:
Bao, You will find it inside key called 'blocks'.
convertToRaw(contentState).blocks.map(el=>el.text)
It will give you an array of raw text.
Unfortunatelly your suggested way using convertToRaw doesnt work because it reindexes all keys to ["0", .., "n"], but the real keys differ when you act with the editor. New ones > n will be added and unused will be omitted.
const rawState = convertToRaw(contentState)
const { entityMap } = rawState;
This entityMap will have list of all entities. But this is an expensive conversion. Because, it will convert whole thing to raw. A better way is loop through blocks and check for entity.
You'll have to look at every character:
const { editorState } = this.state; // assumes you store `editorState` on `state`
const contentState = editorState.getCurrentContent();
let entities = [];
contentState.getBlockMap().forEach(block => { // could also use .map() instead
block.findEntityRanges(character => {
const charEntity = character.getEntity();
if (charEntity) { // could be `null`
const contentEntity = contentState.getEntity(charEntity);
entities.push(contentEntity);
}
});
});
Then you could access it via:
entities.forEach((entity, i) => {
if (entity.get('type') === 'ANNOTATION') {
const data = entity.get('data');
// do something
}
})

Meteor: Underscore _findWhere iteration through loop objects only works in chrome console, in app it says undefined

I'm trying to fetch an object 'single Post' within an object 'Posts' from a json file within meteor, which looks like this.
I found an effective way of doing it, using underscore findWhere to get to it. this is the code
_.findWhere(_.findWhere(CategoryCollection.find().fetch(),
{"_id":"CategoryPublication-5"}).posts,{"ID":46});
however when i put this into meteor, i'm getting undefined
this is the code i used
Template.CategoryArticleSingle.helpers({
articles: function () {
var id = FlowRouter.getParam('ID')
var category = FlowRouter.getParam('category')
console.log(CategoryCollection.find().fetch());
let match = _.findWhere(_.findWhere(CategoryCollection.find().fetch(), {"_id":category}).posts,{"ID": id});
console.log("match",id,category,match);
return match;
}
});
Why am i getting undefined
update.
would this be correct? i substituted the 47 id, with just id so i can use it for any link.
Im getting "category" is read-only error.
Template.CategoryArticleSingle.helpers({
articles: function () {
var id = FlowRouter.getParam('ID')
var category = FlowRouter.getParam('category')
console.log(CategoryCollection.find().fetch());
const category = CategoryCollection.find().fetch().find(c => c._id === id);
let post = null;
if (category) {
post = category.posts.find(p => p.ID === id);
}
console.log("post",id,category,post);
return post;
}
});
There's no need to use lodash/underscore's findWhere. This functionality is built into ES2015. Also, you may consider breaking up the code into a few lines to make it more legible.
const category = CategoryCollection.find().fetch().find(c => c._id === 'CategoryPublication-5');
let post = null;
if (category) {
post = category.posts.find(p => p.ID === 47);
}

Categories

Resources