Convert firebase json to typescript array - arrays

I can easily get the data working in my HTML, but when I have to convert it for visualization purposes it is a struggle.
I get the data as a FirebaseListObservable. In my case there's 3 value-types in each List, but it is only one of them there has to be part of the array. How do I convert a FirebaseListObservable to an array in typescript?
The reason of converting is to use graphs in my app.
Typescript getting the data:
this.measure= this.db.list('/Users/'+this.username+'/Measure');
enter code here
Typescript for chartjs
this.data = [12, 24, 91, 23]
The data has to be the data from the firebase

Declare a empty array data=[];
then get the data with .subscribe()
this.db.list('/Users/'+this.username+'/Measure').subscribe(measures => {
measures.forEach(measure => {
this.data.push(measure.number);//.number should be your field in firebase
})
})
this will fetch all list and search through all items and push your desired values to the array.

FirebaseListObservable is an observable. That means you will get the list itself (=the array you want) when you subscribe to it.
this.measure: FirebaseListObservable<Measure[]> = this.db.list('/Users/'+this.username+'/Measure');
this.measure
.map(measurement => measurement.numbers) // this extracts only numbers field so we have basically array of arrays
.map(numbersArrays => numbersArrays.reduce((curr, prev) => curr.concat(prev))) // so lets concat all those arrays into a single one
.subscribe(numbersArray: number[] => {
console.log(numbersArray);
});
interface Measure {
data: Date;
geolocation: string;
numbers: number[];
}

Related

Return new array of two differents types of arrays according their Id

I have two differents arrays with those models
export interface ProfileMaterialCategory{
id?: string
materialCategory_Name?: string
materialCategory_Id: string
quantity: string
profileId?: string
}
And
import { Category } from "./material-asset-model";
export interface UserAssetsCount {
category: Category
userAssetsCount: number;
}
In my .ts file I'm trying to create a method for getting a combined records for all matching materialCategory_Id / category.Id.
The returned array must have this syntax
[category.name:string, userAssetsCount:string, quantity:string]
I tried with filter and includes but it his not working, or I don't take the problem correctly.
This is the arguments that the method takes.
GetMatch(profileAssets: ProfileMaterialCategory[], userAssets: UserAssetsCount[]): Object[] {
var filteredArray = userAssetsAllowed.filter(
as
setAllowed => userAssetsCount.some(
assetCount => assetCount.category.id.toString() == assetAllowed.materialCategory_Id)
return filteredArray
}
When I filter, I receive an element of the array when the condition is true, but it's an element from one of the array, I can't take value from the other.
So, I've succed in one way to do what I needed.
First I created a new DTO model:
export interface UserAssetMatch {
category: Category,
allowed: string,
owned: number
}
Then I make a foreach() loop on one array, and use a filter() on the second array. I keep the matching elements in an intermediate array.
If there is something in the intermediate array, I push the informations that I need in the DTO.
GetMatch(userAssetsAllowed: ProfileMaterialCategory[], userAssetsCount: UserAssetsCount[]): UserAssetMatch[] {
var matchArray: UserAssetMatch[] = [];
userAssetsCount.forEach(userAsset => {
var profileAssets = userAssetsAllowed.filter(userAssetAllowed => userAsset.category.id.toString() == userAssetAllowed.materialCategory_Id);
if (profileAssets.length > 0) {
matchArray.push({
category: userAsset.category,
owned: userAsset.userAssetsCount,
allowed: profileAssets[0].quantity
})
}
});
return matchArray;
I don't think it is a good way to do, but it works. If someone have a better/faster/cleaner way to do, please tell me :)

unable to access dynamic object property and store to state in react

I'm trying to grab these arrays from one of the nasa open apis -> https://api.nasa.gov/neo/rest/v1/feed?start_date=START_DATE&end_date=END_DATE&api_key=API_KEY
I have a dynamic date in the params so the objects returned match the date, is there any way I can use my date (even though its a string) and turn it into a 'key' value so I can dynamically grab the objects I need?
like => "2021-08-26" would reference { 2021-08-26: [{},{},{}...] }
I have included my code so far with what I've tried, currently I'm trying to just select all the keys inside the {near_earth_objects} using forEach but I'm still getting an error data.near_earth_objects.forEach is not a function
constructor(){
super();
this.state={
asteroids:[],
time: []
}
}
//grab the current time (year-month-day) and store it in the state
componentWillMount(){
var today = new Date();
var start = today.getFullYear()+'-'+0+(today.getMonth()+1)+'-'+today.getDate();
var end = today.getFullYear()+'-'+0+(today.getMonth()+1)+'-'+(today.getDate()+1);
this.setState({time: [start,end]})
}
componentDidMount(){
fetch(`https://api.nasa.gov/neo/rest/v1/feed?start_date=${this.state.time[0]}&end_date=${this.state.time[1]}&api_key=ipAxYzaENbqRKb7GgzFPcH6QUBsHXY3QKB7uXOf5`
)
.then(response => response.json())
.then((data) => {
let asteroids = []
data.near_earth_objects.forEach((arr)=>{
asteroids.push(arr)
})
this.setState({asteroids:asteroids})
});
}
here is an example of the logged data I'm trying to access
It's important to note that the data is coming back as an object where the values are arrays. Since the return data is an object you cannot iterate over it.
However, to get the data you can Object.values(object) (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values) to get an array of the values. This will return something that looks like [ [...], [...] ]
After that you can iterate over this information.
In the end your code should look something like this:
Object.values(data.near_earth_objects).forEach((arr)=>{
asteroids.push(...arr)
})

How to sort how you want the the data from firestore

I have a firestore with lessons, see the picture below, I get from the firestore the title property from each object and display it in the browser, but everytime I refresh the website the lessons are sorted by how they want, why is that happening? I want to sort them how I want, I want to start with 'Introduction' and so on, how can I do that? I think the orderBy() is not working here.
As you see in the image above, the order in the firestore is alphabetical, but in my page is sorted by its own, see the picture below.
I want the result to be by in a specific order, for example we have the following titles, these titles are from the firestore: "Display", "Introduction", "Alignment", my problem is that these 3 titles are in a new order every time I refresh the website, I want them to be: "Introduction", "Alignment", "Display". In my case I have more titles but this is what's happening, I don't know how to align them how I want or even alphabetical if is possible.
Below is the code that I used to get the data from firestore:
useEffect(() => {
db.collection("users")
.doc(`${user.uid}`)
.get()
.then((doc) => {
const allData = { ...doc.data(), id: doc.id };
const intoArray = Object.entries(allData);
intoArray.sort(); // I used sort here because I had the same problem
// (every time a new order) with the
// data when I converted it to an array
const getCSSLessons = intoArray[0][1];
const cssData = Object.values(getCSSLessons);
setCss(cssData);
const getHTMLLessons = intoArray[1][1];
const htmlData = Object.values(getHTMLLessons);
setHtml(htmlData);
const getResLessons = intoArray[3][1];
const resData = Object.values(getResLessons);
setRes(resData);
})
.catch((error) => console.log(error));
}, [user]);
I tried using sort(), for a variable (htmlData) but its not working.
Also, I use map() to display them, if this helps you to answer to my question.
If you use sort without any argument, it will sort array elements alphabetically. It looks like your array elements are arrays, which will end with unexpected behaviors. Use sort argument to ensure it uses your own sorting rules. For example:
const intoArray = Object
.entries(allData)
// I don't know what should be the sorting algorithm
// As an example, I consider each element (`a` and `b`) to
// be arrays and compare both first element as a Number
.sort( (a, b) => a[0] - b[0])
Edit
A more secure way to find elements in an array is to use find:
const getCSSLessons = intoArray[0]
.find( element => element.name === 'CSS Lessons');
I was doing something unnecessary as you see in the first picture I had a main object css and in that object I had sub-objects like alignment and in the sub object I had the properties that I want to display, that sub object was unncessary, istead of sub objects with a pre defined name, I let the firebase to count the sub objects and add as a name a number and the order is the same as I wanted to be.
The code that I used to add data to firebase:
fire
.auth()
.createUserWithEmailAndPassword(email, password)
.then((cred) => {
return db
.collection("users")
.doc(cred.user.uid)
.set({
css: [
{
title: "Introduction",
path: "/css3/introduction",
},
{
title: "Priority",
path: "/css3/priority",
},
],
});

How to fetch value from array which came from json in Angular 5 app?

I have the following JSON definitions:
export class Company {
name: string;
trips : Trip[] = [];
}
export class Trip{
id: number;
name: string;
}
I am able to see the trips in the console using:
console.log(this.company);
In the component I have the following method:
if(this.company) {
Object.keys(this.company.trips).forEach((data) => {
console.log(data);
});
}
What I am getting in the console is the trip's properties names which is "id" and "number".
I would like to know how to access the value.
According to your data structure, you should not even try to do Object.keys what you should be doing as the Trip is an object, is something like following in which you treat the iteration object as a real Trip object
if(this.company && this.company.trips){
this.company.trips.forEach((trip:Trip) => {
console.log(trip.id + '\n' + trip.name);
});
}
if you have any issue with this piece of cod then make sure you are correctly doing your deserialization process and objects are getting cast properly.

Why can't I update its element value correctly within Array.forEach() loop in Angular 7?

I'm testing Material Table(mat-table) on Angular 7, here's a weird issue I ran into.
Send a request to jsonplaceholder for fake data in users.service
export class UsersService {
API_BASE = 'https://jsonplaceholder.typicode.com/users';
constructor(private http: HttpClient) {}
getUsers(): Observable<object> {
const url = this.API_BASE;
return this.http.get(url);
}
}
Because jsonplaceholder only returns 10 rows of data, so I concatenate the data for a larger array, say, 30 rows for testing pagination feature with ease. Meanwhile, update the 'id' field with iterate index so the 'id's looks like 1,2,3...30, instead of 1,2,3...10,1,2,3...10,1,2,3...10, which is a result of concatenation, that's it, nothing special.
users.component:
ngOnInit(): void {
this.userService.getUsers().subscribe((users: UserData[]) => {
users = users.concat(users, users);
users.forEach((user, index) => (user.id = index +1));
console.log(users);
this.dataSource.data = users;
});
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
Although the table shows up beautifully, but the 'id's column looks weird, they are not 1,2,3...30 sequentially, instead, they are 21,22,23...30,21,22,23...30,21,22,23...30
I tried to print out the user.id inside the forEach loop, it's all good.
users.forEach((user, index) => {
user.id = index + 1;
console.log(user.id);
});
Where did I go wrong with this? Any clue? Thanks.
P.S, API used in the code: https://jsonplaceholder.typicode.com/users
even though you have 30 array elements after concatenating the array twice, you still only have 10 unique objects. the Object behind users[20] is the same as users[0], so you override the id of the already processed objects from index 10 to 29
you can fix this by creating a copy of each object. There are many ways too do this. a very simple way is serializing and deserializing using JSON.stringify and JSON.parse:
users.forEach(user => users.push(JSON.parse(JSON.stringify(user))));

Resources