I use firebase and I am creating a follow system which pushes in firebase my data like that when I follow:
firebase.database().ref('followers/' + followedId).update({ [this.userId]: true });
firebase.database().ref('followings/' + this.userId).update({ [followedId]: true });
Then If I would like to display my list of followers / followings, I need an array of object {followedId: true}
I need to change the format of the result [{followedId: true}] to an array of followedId. Hope is more clear.
If your results look like {uid1: true, uid2: true, uid3: true, uid4: true}
const results = {uid1: true, uid2: true, uid3: true, uid4: true}
const followers = Object.keys(results)
console.log(followers) // ["uid1", "uid2", "uid3", "uid4"]
If you need them formatted as per your comment:
const results = {uid1: true, uid2: true, uid3: true, uid4: true}
const followers = Object.keys(results).map(id => ({ uid: id, checked: true }))
console.log(followers)
Related
I am allowing my users to create different roles for themselves within my svelteKit application.
I have a text input with a button that adds that value to an array and shows in the div below.
I need to convert the array into a tiered JSON object so I can add it to my Postgres database role_permissions column as JSONB. I have tried JSON.stringify() and JSON.parse() but I cannot get it to work.
Ideally formatted like this:
{
"role_name"{
"permission": true,
"permission": true,
...
}
"role_name_2"{
"permission": true,
"permission": false,
...
}
}
While my users can create roles with custom names the permissions available are all the same e.g.:
can_add_members: false,
can_delete_members: false,
can_edit_members: false,
can_create_roles: false,
can_delete_roles: false,
can_edit_roles: false,
can_assign_roles: false,
can_create_projects: false,
can_delete_projects: false,
can_edit_projects: false,
can_publish_projects: false,
can_view_projects: false,
can_assign_members_to_projects: false,
I can't figure out how to convert the object into a tiered JSON format. I know I need some sort of key outside of each object but I do not know how to do that.
This is how they appear in console.log()
{name: "Partner", can_add_members: false, can_delete_members: false, can_edit_members: false, can_create_roles: false, …}
{name: "Associate Partner", can_add_members: false, can_delete_members: false, can_edit_members: false, can_create_roles: false, …}
The actual code:
let newItem = '';
// An array of the roles names that will also be saved to the database as is.
let roleList = [];
// The array that needs to be converted to JSON
let roleListWithPermissions = [],
function addToList() {
roleList = [...roleList, {text: newItem,}];
roleListWithPermissions = [...roleListWithPermissions, {
"name": newItem,
"can_add_members": false,
"can_delete_members": false,
"can_edit_members": false,
"can_create_roles": false,
"can_delete_roles": false,
"can_edit_roles": false,
"can_assign_roles": false,
"can_create_projects": false,
"can_delete_projects": false,
"can_edit_projects": false,
"can_publish_projects": false,
"can_view_projects": false,
"can_assign_members_to_projects": false
}];
newItem = '';
console.log("ROLE LIST",roleList)
console.log("PERMISSIONS LIST",roleListWithPermissions)
}
One approach is below, with explanatory comments in the code:
// the original Object as described/shown in the question:
let source = [{
name: "Partner",
can_add_members: false,
can_delete_members: false,
can_edit_members: false,
can_create_roles: false,
},
{
name: "Associate Partner",
can_add_members: false,
can_delete_members: false,
can_edit_members: false,
can_create_roles: false,
}
],
// here we use Array.prototype.map() to iterate over the Array of Objects:
rolePermissions = source.map(
// using destructuring assignment to retrieve the 'name'
// property from the Array-element (the Object),
// and assigning all remaining property-value pairs
// to the 'rest' variable:
({
name,
...rest
}) => {
// here we return a new Object, with the computed value of the
// 'name' variable to set the property equal to the value of the
// variable rather than the String of 'name':
return {
// and the property-value equal to the Object containing the
// rest of the key-value pairs:
[name]: rest
};
}),
// converting the Array of Objects into a JSON string:
jsonRolePermissions = JSON.stringify(rolePermissions);
// logging that JSON string to the console:
console.log(jsonRolePermissions);
Reference:
Array.prototype.map().
Destructuring assignment.
JSON.stringify().
Object initializer.
you can transform roleListWithPermissions array to an object.
const finalResult =
roleListWithPermissions.reduce((result, current) => {
result[current.name]= {...current};
delete result[current.name].name;
return result;
}, {})
I have such query
const companiesByEmployeesOfProdUnits = await models.CompanyProductionUnitNonCeased
.findAll({
raw: true,
limit: 5,
offset: 0,
attributes: [[sequelize.fn('DISTINCT', sequelize.col('company_id')), 'company_id']],
include: [{
model: models.ProductionUnitCore,
as: 'production_unit',
include: [{
model: models.EmployeeInformationProductUnit,
as: 'employee_information_product_units',
attributes: ['number_of_employees'],
where: { is_current: true, ...rangeOfEmployees }
}]
}]
})
There are more then 2 million records. How can I get 5 records? Because now I have only one but I'm sure about correct where conditions and I don't understand why I get only one instead of 5.
I need only to add 'required: true' field for each 'include' object
I have a problem finding a solution on how to fill empty nested array by using the useState hook. I'm a react beginner and I have might miss something. In steps below I shall try to summarize the problem.
1.) I receive this data format as props - {question}:
{
category: "General Knowledge"
correct_answer: "Arby's"
difficulty: "easy"
incorrect_answers: (3) ['McDonald's', 'Burger King', 'Wendy's']
question: "In which fast food chain can you order a Jamocha Shake?"
type: "multiple"
}
What my goal output is ty create an object with this structure:
value: "Opel",
isClicked: false,
isCorrect: true,
incorrect_answers: [
{isClicked: false, value: "Bugatti"},
{isClicked: false, value: "Bentley},
{etc...}
]
With this approach I achieve the result, but I would like to find a more correct react way.
useEffect(() => {
const obj = {
value: question.correct_answer,
isClicked: false,
isCorrect: true,
incorrect_answers: []
}
question.incorrect_answers.map((item) =>
obj.incorrect_answers.push({
value: item,
isClicked: false,
})
)
setAnswers(obj)
}, [])
My goal is to have mentioned data structure formed in useState with the right approach on how to access nested arr and fill it with objects.
a) I use the useState for setting up state and its data structure for answers obj.
const [answers, setAnswers] = useState({
value: question.correct_answer,
isClicked: false,
isCorrect: true,
incorrect_answers: [
//I want multiple objects {value: '...', isClicked: ...},
// Would be nice if I was able to insert objects in this a) step.
]
})
b) Perhaps on the useEffect or on some other funcion I want to fill incorect_answers array with objects.
useEffect(() => {
// c) Im accesing the answers state and filling incorect_answers with obj
setAnswers(prevState => {
return {
...prevState,
incorrect_answers: [{
value: question.incorrect_answers.map((item) => item),
isClicked: false,
isCorrect: false
}]
}
})
// d) my output:
/* {
value: "Opel",
isClicked: false,
isCorrect: true,
incorrect_answers: [
{isClicked: false, value: [bugatti, bentley, bmw, citroen]},
]
} */
}, [])
If you're using map you shouldnt ignore the response from it, and you don't need to push to the array
useEffect(() => {
const obj = {
value: question.correct_answer,
isClicked: false,
isCorrect: true,
incorrect_answers: question.incorrect_answers.map(item => ({
value: item,
isClicked: false
}))
}
setAnswers(obj)
}, [])
The same method can be used when first filling your state
const [answers, setAnswers] = useState({
value: question.correct_answer,
isClicked: false,
isCorrect: true,
incorrect_answers: question.incorrect_answers.map(item => ({
value: item,
isClicked: false
}))
})
How can I pass object keys into an array that are true. So that I can use this array for filtering?
Example Object:
let results = [
{name: marc, isAlumnus: true, isScholar: true, isTrustee: false},
{name: franz, isAlumnus: false, isScholar: true, isTrustee: false},
{name: Hugo, isAlumnus: true, isScholar: true, isTrustee: false},
]
And the attempt of a function!
getActiveStatusGroups (results) {
let res = [];
res = results.map((item) => {
if (item) {
res.push('isScholar');
}
});
return res;
},
let statusArray = getActiveStatusGroup(this.results)
You can get an array of the property names from Object.keys, or an array of [name, value] arrays from Object.entries, depending on what you want to do.
It's kind of hard to tell what output you want as a result, but for instance, this returns an array of arrays, where the inner arrays are the names of the properties for which the value was truthy:
getActiveStatusGroups(results) {
return results.map(entry =>
Object.keys(entry).filter(key => entry[key])
);
}
Live Example:
let results = [
{isAlumnus: true, isScholar: true, isTrustee: false},
{isAlumnus: false, isScholar: true, isTrustee: false},
{isAlumnus: true, isScholar: true, isTrustee: false},
];
function getActiveStatusGroups(results) {
return results.map(entry =>
Object.keys(entry).filter(key => entry[key])
);
}
console.log(getActiveStatusGroups(results));
Filtering is pretty simple in JavaScript
The methods name is right there in your title, yet you failed to recognize it. Use filter instead of map. The filter() method creates a new array with all elements that pass the test implemented by the provided function.
Here's your code
let results = [
{name: marc, isAlumnus: true, isScholar: true, isTrustee: false},
{name: franz, isAlumnus: false, isScholar: true, isTrustee: false},
{name: Hugo, isAlumnus: true, isScholar: true, isTrustee: false},
]
getActiveStatusGroups(group) {
// returns the element if the condition is true
return results.filter(result => result[group])
}
That's it
console.log(getActiveStatusGroups('isAlumnus'))
console.log(getActiveStatusGroups('isScholar'))
console.log(getActiveStatusGroups('isTrustee'))
I'm having trouble fetching data on firebase with complex structure.
I have a structure like this:
place1: {
visits: {
user1: true,
user2: true,
user3: true,
user4: true
}
},
place2: {
visits: {
user1: true,
user3: true,
user4: true
}
},
place3: {
visits: {
user2: true,
user3: true,
user4: true
}
}
How do you query all the users that has been to all the places?
Thank you so much for your help!
Your current data structure allows you to efficiently fine all users that have been to a specific place. It does not allow you to efficiently query all places that a specific user has been to.
To allow that second query, you should add a second data structure:
user1: {
place1: true,
place2: true
},
user2: {
place1: true,
},
user3: {
place1: true,
place3: true
},
user4: {
place1: true,
place2: true,
place3: true,
place4: true
}
With this additional structure (often called an inverted index) in place, you can find the places each user went to.
Since you now have two structures, you will need to ensure you add each visit to both places. A single multi-location update can accomplish that:
function recordVisitor(uid, placeid) {
var updates = {};
updates[`/userVisits/${uid}/${placeid}`] = true;
updates[`placeVisitors/${placeid}/${uid}`] = true;
firebase.database().ref().update(updates);
}
Also see my answer for a related use-case (querying items in categories) that also requires an inverted index: http://stackoverflow.com/questions/40656589/firebase-query-if-child-of-child-contains-a-value