how to fetch data from firebase realtime database in react js - javascript

there I am studying to fetch data from firebase realtime database I watched various youtube videos and few posts and got this far code is kinda right and don't know where I made a mistake I would be happy if someone helps me I have attached both JSON and react code for better understanding. I was only able to fetch IDs only from the database ...
here is code
import React, { Component, Fragment } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import firebase from './firebase.js';
class App extends Component {
constructor(props) {
super(props);
this.state = {
accounts: [],
users: [],
}
}
componentDidMount() {
const accountRef = firebase.database().ref('accounts');
accountRef.on('value', (snapshot) => {
let accounts = snapshot.val();
let newState = [];
for (let account in accounts) {
newState.push({
id:account,
account: accounts[account].account,
title: accounts[account].title,
})
}
this.setState({
accounts:newState,
})
})
const userRef = firebase.database().ref('users');
userRef.on('value', (snapshot) => {
let users = snapshot.val();
let newUserState = [];
for (let data in users) {
newUserState.push({
id:data,
account:users[data].account,
name: users[data].name,
})
console.log(data)
}
})
}
render() {
return (
<Fragment >
<section>
<div>
<h2>User Details</h2>
{this.state.accounts.map( data =>
<div key={data.id}>
{console.log(data.title)}
<h4 >{data.account}</h4>
<h4 >{data.name}</h4>
</div>
)}
</div>
<div>
<h2>User Apps</h2>
{this.state.accounts.map( accounts =>
<div key={accounts.id}>
{/* {console.log(accounts.title)} */}
<h4 >{accounts.id}</h4>
<h4 >{accounts.title}</h4>
</div>
)}
</div>
</section>
</Fragment>
);
}
}
export default App;
here is josn file structure
{
"accounts": {
"-Kd_teAAXcw2b5MyFPIT": {
"apps": {
"cuckoosnest": {
"title": "One Flew Over The Cuckoo’s Nest"
}
}
},
"-Kd_ZCjRYSGzISxY_5Wi": {
"apps": {
"psycho": {
"title": "Psycho"
}
}
},
"-Kda3ClE2i0vZzyh7uh0": {
"apps": {
"addams": {
"title": "The Addams Family"
}
}
},
"-Kda8nknT6-XyJE_SjCl": {
"apps": {
"princess-bride": {
"title": "The Princess Bride"
}
}
},
"-KdeN0Yk89J4l5hMJ6Ea": {
"apps": {
"mi": {
"title": "Mission: Impossible"
}
}
},
"-KdWbLKO0uZ0W5LYe9gj": {
"apps": {
"bladerunner": {
"title": "Blade Runner"
}
}
},
"-KdWI6HAF0_wh9-NTEpe": {
"apps": {
"dragontattoo": {
"title": "The Girl With The Dragon Tattoo"
}
}
},
"-KdWPnObbAbjd9lHX___": {
"apps": {
"nakedgun": {
"title": "Naked Gun"
}
}
},
"-Ke4dwlXoIBXPgB8v9Pt": {
"apps": {
"scarface": {
"title": "Scarface"
}
}
},
"-Ke4YQMM3aTQ-u19uIuv": {
"apps": {
"fargo": {
"title": "Fargo"
}
}
}
},
"users": {
"00L91c7cvUaghNmGlC0lJa9eZ102": {
"account": "-Kd_teAAXcw2b5MyFPIT",
"name": "Randle McMurphy"
},
"0YRaZC6EUrc5sc8Ab4AR7Zp7ig93": {
"account": "-Kd_ZCjRYSGzISxY_5Wi",
"name": "Norman Bates"
},
"11yVrZ6TK3ZuKpITF8UVGF4ILlC3": {
"name": "Wednesday Addams",
"account": "-Kda3ClE2i0vZzyh7uh0"
},
"2d0WRN7v3lYNc9DX02yMfLmTiIM2": {
"name": "Inigo Montoya",
"account": "-Kda8nknT6-XyJE_SjCl"
},
"39IY5AX8zfgtztbQ4RFCJ0dSsel1": {
"name": "Ethan Hunt",
"account": "-KdeN0Yk89J4l5hMJ6Ea"
},
"39VBFQdD1qNgNydJ2A6kdoVLhIc2": {
"name": "Roy Batty",
"account": "-KdWbLKO0uZ0W5LYe9gj"
},
"3ACrWNFyEVObZaWMcMmZq9C045h1": {
"name": "Lisbeth Salander",
"account": "-KdWI6HAF0_wh9-NTEpe"
},
"3C9RrP8bxAVRhRcPHNBOpc5oTo83": {
"name": "Frank Drebin",
"account": "-KdWPnObbAbjd9lHX___"
},
"3kqJLMDHO2N5APYHpv5H8VtRXoj1": {
"name": "Tony Montana",
"account": "-Ke4dwlXoIBXPgB8v9Pt"
},
"44w3em7XKfhKcSSvQVk8hJIfsBQ2": {
"name": "Marge Gunderson",
"account": "-Ke4YQMM3aTQ-u19uIuv"
}
}
}

To fix the users data you need to do this
const userRef = firebase.database().ref('users');
userRef.on('value', (snapshot) => {
let newUserState = [];
snapshot.forEach(data => {
const dataVal = data.val()
newUsersState.push({
id: data.key,
name: dataVal.name,
account: dataVal.account
})
})
})
for the accounts data i am not sure what information you are trying to add to the state.... you are trying to call .account & .title but that does not exist in the snapshot.. but either way your data is poorly structured and makes it difficult to manage

Related

Recursive function returns weird output?

So i have this problem where i need to fill a list with objects of children's ids,names and parents ids and names for further backend work.
When i select a child and I recursively fill the list it gives me this output
[
{
"_id": "6328354914a6c4002121c2c6",
"name": "sss21"
},
{
"_id": "6328354914a6c4002121c2c6",
"name": "ss21"
},
{
"_id": "6328354914a6c4002121c2c6",
"name": "s1"
},
{
"_id": "6328351214a6c4002121c2c5",
"name": "new"
},
{
"_id": "6328354914a6c4002121c2c6",
"name": "s1"
},
{
"_id": "6328354914a6c4002121c2c6",
"name": "ss21"
},
{
"_id": "6328354914a6c4002121c2c6",
"name": "sss21"
}
]
I use this function to fill the list
selectionOutput(node) {
const id = node._id;
const name = node.name;
if (node.parent !== null) {
this.selection.push({_id: id, name: name});
this.selectionOutput(node.parent);
}
this.selection.push({_id: id, name: name});
return this.selection;
}
The function expects a node with parent nodes which in this case is this one
{
"_id": "6328351214a6c4002121c2c5",
"name": "new"
}
the other 3 like "s1, ss21 and sss21" are its children.
How can i make the function return just
[
{
"_id": "6328351214a6c4002121c2c5",
"name": "new"
},
{
"_id": "6328354914a6c4002121c2c6",
"name": "s1"
},
{
"_id": "6328354914a6c4002121c2c6",
"name": "ss21"
},
{
"_id": "6328354914a6c4002121c2c6",
"name": "sss21"
}
]
I should probably add that my data structure looks like this:
{
"_id": "6328351214a6c4002121c2c5",
"name": "new"
"parent": null,
"children": {
"_id": "6328354914a6c4002121c2c6",
"name": "s1",
"parent": {"_id": "6328351214a6c4002121c2c5","name": "new"}
"children": {
"_id": "6328354914a6c4002121c2c6",
"name": "ss21",
"parent": {"_id": "6328354914a6c4002121c2c6","name": "s1"}
"children":{...} Hope you get the point
}
},...
}
Also my function is fed with and Object that is a child and it goes up a level from there. For example child3(parent: child2) -> child2(parent:child1) -> child1(parent: parent) -> parent. I want to map all the ids all the ancestors of the initial object including the id of the initial one.
Looking at your data structure you can try this approach:
data.reduce((accum, item) => {
const childs = [];
const getChilds = ({ _id, name, children}) => {
childs.push({ _id, name});
if (children) getChilds(children);
};
if (item.children) getChilds(item.children);
return [...accum, { _id: item._id, name: item.name, children: childs }];
}, [])
OR this one if you want all data at root level
data.reduce((accum, item) => {
const childs = [];
const getChilds = ({ _id, name, children}) => {
childs.push({ _id, name});
if (children) getChilds(children);
};
if (item.children) getChilds(item.children);
return [...accum, { _id: item._id, name: item.name }, ...childs];
}, [])
``
One push is all that the function needed. I moved the push before the if statement and it works fine now.
selectionOutput(node) {
const id = node._id;
const name = node.name;
this.selection.push({_id: id, name: name});
if (node.parent) {
this.selectionOutput(node.parent);
}
return this.selection;
}

How to fetch particular object in a document of collection mongoDB?

I have this document in a collection. I want to fetch a particular product object which matches the query. I have a const query that fetches the product slug from the URL. There are product slugs defined in the database. What I want is prop product should contain only that object which matches the product slug.
MongoDB data
{
"productListing": {
"filters": [
{
"id": "brand",
"name": "Brands",
"options": [
{ "value": "Casio", "label": "Casio", "checked": false },
{ "value": "Yamaha", "label": "Yamaha", "checked": false }
]
}
],
"products": [
{
"sku": "KEY-CAS-001-GRN",
"product_brand": "Casio",
"product_name": "Casio SA-46 32 Mini Keys Musical Keyboard (Black/Green)",
"product_slug": "casio-sa-46-32-mini-keys-musical-keyboard"
},
{
"sku": "KEY-CAS-002-GRY",
"product_brand": "Casio",
"product_name": "Casio SA-47A Electronic Keyboard, Black (32 Keys)",
"product_slug": "casio-sa-47a-mini-keys-electronic-keyboard"
},
]
}}
product.js
export async function getServerSideProps(context) {
context.res.setHeader(
'Cache-Control',
'public, s-maxage=20, stale-while-revalidate=59'
)
var query = { product_slug: context.params.productslug };
const { db } = await connectToDatabase();
const result = await db
.collection("portable_keyboards").find({})
if (!result) {
return {
notFound: true,
}
}
return {
props: {
product: JSON.parse(JSON.stringify(result)),
},
};
}
export default function Product({ product }) {
//rest of the code
}

Put JSON data inside another object of the same JSON

I need to put the images that are on "included" into "data:{relationships: { field_imagen: { data" but the problem is that i just managed to put only the first image into every index using map and find
noticiasImages.forEach(function(data: { relationships: { field_imagen: {data: {id:any}}}} ) {
var nestedArray = noticiasData.map((noticiasImages: { id: any; }) => noticiasImages == noticiasData);
data = nestedArray && noticiasImages || noticiasData;
});
And this is my json (example node)
{
"data": [
"relationships": {
"field_imagen": {
"data": [
{
"type": "file--file",
"id": "dba917f0-b80f-45ed-a569-69f2ba2b482d",
}
],
}
]
},
this is the included object, who is in the same level as data
"included": [
"attributes": {
"drupal_internal__fid": 8798,
"langcode": "es",
"filename": "_DSC6472 - copia.jpg",
"uri": {
"value": "public:\/\/2019-11\/_DSC6472 - copia.jpg",
"url": "\/sites\/default\/files\/2019-11\/_DSC6472%20-%20copia.jpg"
},
},
,
Expected Result:
"data": [
"relationships": {
"type": "node--actualidad_institucional",
"id": "71514647-af49-4136-8a28-9563d133070a",
"field_imagen": {
"data": [
{
"type": "file--file",
"id": "dba917f0-b80f-45ed-a569-69f2ba2b482d",
"uri": {
"value": "public:\/\/2019-11\/_DSC6472 - copia.jpg",
"url": "\/sites\/default\/files\/2019-11\/_DSC6472%20-%20copia.jpg"
},
}
}
},
I put the uri from included into field_imagen. Tried to resolve like that, but it just put only the first image of the Array from the included object in every node:
showNoticias() {
this.frontService.getNoticias()
.subscribe((data: Noticias) => {
this.noticiasImages = Array.from(data.included);
this.noticiasData = Array.from(data.data);
let noticiasImages = this.noticiasImages.map((data: {id: any}) => data.id);
let noticiasData = this.noticiasData.map((data:{relationships: { field_imagen: { data: { id: any; }}}}) => data.relationships.field_imagen.data.id);
noticiasImages.forEach(function(data: { relationships: { field_imagen: {data: {id:any}}}} ) {
var nestedArray = noticiasData.map((noticiasImages: { id: any; }) => noticiasImages == noticiasData);
data = nestedArray && noticiasImages || noticiasData;
});
console.log(data);
});
}
Hope you can help me, thanks!
UPDATE: tried that but didnt work like expected
let merged = data.data.map((data:{relationships: { field_imagen: { data: any }}}) => Object.assign({}, noticiasImages));
console.log(data)
console.log(merged)
Sometimes using regular for loops are a better option. Using map with objects that have that many properties can get confusing. And using forEach will not give you access to the i index of the iteration in the loop, which makes things easier in this case.
for (let i = 0; i < obj.included.length; i++) {
let uri = obj.included[i].attributes.uri;
obj.data[i].relationships.field_imagen.data[0] = {
...obj.data[i].relationships.field_imagen.data[0],
...uri
}
}
console.log(obj)
Output:
{
"data": [
{
"relationships": {
"field_imagen": {
"data": [
{
"type": "file--file",
"id": "dba917f0-b80f-45ed-a569-69f2ba2b482d",
"value": "public://2019-11/_DSC6472 - copia.jpg",
"url": "/sites/default/files/2019-11/_DSC6472%20-%20copia.jpg"
}
]
}
}
}
],
"included": [
{
"attributes": {
"drupal_internal__fid": 8798,
"langcode": "es",
"filename": "_DSC6472 - copia.jpg",
"uri": {
"value": "public://2019-11/_DSC6472 - copia.jpg",
"url": "/sites/default/files/2019-11/_DSC6472%20-%20copia.jpg"
}
}
}
]
}

Getting Nested JSON data using VueJS

I want to get a nested JSON data using VueJS, but I'm having trouble understanding how to do that (I'm new to VueJS). The data is as follows:
{
"title": "Editor",
"key": "Editor_one",
"attributes": {
"holder",
},
"properties": [
{
"title": "Date :",
"attributes": {
"Path": "0/9",
}
},
{
"title": "2000/06/17",
"key": "date_ident",
"attributes": {
"Path": "0/10",
}
},
{
"key": "zero_vector",
"attributes": {
"Path": "0/11",
},
"properties": [
{
"title": "File",
"attributes": {
"Path": "0/11/0",
},
},
{
"key": "zero_date",
"attributes": {
"Path": "0/17",
},
"properties": [
{
"title": "2000/06/18",
},
My current vueJS code attempt is as follows:
<div v-for="editDate in vectors.slice(0,1)" v-bind:key="editDate.id" class="row-control">
<div v-if="editDate.title = '2000/06/2018'">
<label style="margin-right: 10px" v-bind="response">{{editDate.title}}</label>
<input
type="text"
v-model="date"
name="date"
placeholder="Add Date"
/>
</div>
async created() {
try {
const response = await axios.get('http://localhost:8080/');
this.vectors = response.data.properties; //assign data from response to 'vectors'
} catch (e){
console.error(e);
}
},
I want to get the data: "title": "2000/06/18" from the key: "zero_date" and bind it to the 'input' tag. Thanks!
Does that help? Can properties inside "zero_date" have more than one item?
{
async created() {
try {
const response = await axios.get('http://localhost:8080/');
this.vectors = response.data.properties; //assign data from response to 'vectors'
} catch (e){
console.error(e);
}
},
computed: {
zeroDate: {
get() {
return this.vectors.find(vector => vector.key === 'zero_date').properties[0].title
},
set(newValue) {
this.vectors.find(vector => vector.key === 'zero_date').properties[0].title = newValue
}
}
}
}

Trying to render data on from database on page REACT

I'm finally not getting any errors, but now I can't get the data coming in from my database to render on the page
Here is the trouble component:
import React, { Component } from 'react';
import axios from 'axios';
export default class ListPets extends Component {
constructor(props) {
super(props);
this.state = {
pets: {},
isLoaded: false,
}
}
componentDidMount = () => {
This. getPets ();
};
getPets = async () => {
const res = await axios.get('http://localhost:5000/pets');
const pets = res.data;
this.setState({ isLoaded: true, pets });
console.log('Data has been received!');
}
render() {
console.log('State: ', this.state);
const { isLoaded, pets } = this.state;
if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<div>
<ul>
{Object.entries(pets).map(([key, pet]) => (
<li key={key}>{pet.name}</li>
))}
</ul>
</div>
);
}
}
}
Here is the data I'm trying to render from my database
{
"_id": "5dfe7b55a3678700785c9b69",
"species": "Collie",
"name": "Dax",
"age": "2",
"petImage": "C:\\fakepath\\brown-and-white-dog-4633734_640.jpg"
}
{
"_id": "5dfe828af33fa800ac8b49c8",
"species": "lab",
"name": "bea",
"age": "1",
"petImage": "C:\\fakepath\\puppy-1207816_640.jpg"
}
{
"_id": "5dfea025ea5cc2016e528f5a",
"species": "pittbull",
"name": "nina",
"age": "3",
"petImage": "C:\\fakepath\\pitbull1.jpg"
}
{
"_id": "5dfea0c229d0d4017b982f35",
"species": "pittbull",
"name": "nina",
"age": "3",
"petImage": "C:\\fakepath\\pitbull1.jpg"
}
{
"_id": "5dfea63eb1505e018a2ba363",
"species": "pittbull",
"name": "Gina",
"age": "3",
"petImage": "C:\\fakepath\\pitbull1.jpg"
}
{
"_id": "5dfea7a1fed64001b9632b8f",
"species": "pittbull",
"name": "kat",
"age": "2",
"petImage": "C:\\fakepath\\pitbull1.jpg"
}
If you are getting the data use the state
return (
<div>
<ul>
{this.state.pets.map(pet => (
<li key={pet.id}>{pet.name}</li>
))}
</ul>
</div>
);
}
}
}

Categories