React Flexbox-grid build dynamically - meteor

i hope you can help me with this. I have been trying for quite some time now to creat a grid using flexbox-grid in react dynamically. What i want to achieve for now is to create a new row every 3 elements. I have been playing around with the meteor simple-todos example and i am trying to extend it to learn more about it.
What i have so far in terms of code is:
renderTasks() {
let filteredTasks = this.props.tasks;
return filteredTasks.map((task, i) => {
const currentUserId = this.props.currentUser && this.props.currentUser._id;
const showPrivateButton = task.owner === currentUserId;
if (i % 3 == 0){
console.log("row " + i);
return (
<Row>
<Task
key={task._id}
task={task}
showPrivateButton={showPrivateButton}
/>
</Row>
);
}else{
console.log("col " +i );
return (
<Task
key={task._id}
task={task}
showPrivateButton={showPrivateButton}
/>
);
}
});
}
The problem here is that i cant leave the row open and have to close it immediatly. I assume this should not be to hard to achieve but i googled quite a bit and could not find anything :(

Here's what I would do. First, I would group the tasks according to the row where they should be placed. Then I would have an array of arrays, more or less like this:
[
[ task_1, task_2, task_3 ],
[ task_4, task_5 ]
]
Then I would map over this array to render each row. Finally, to render a row, I would map over that row's tasks and render each task.
Something like this:
renderTasks() {
let filteredTasks = this.props.tasks;
let taskRows = filteredTasks.reduce(function (rows, task, i) {
let rowIndex = Math.floor(i / 3);
if (i % 3 == 0) {
rows[rowIndex] = [task]
} else {
rows[rowIndex].push(task)
}
return rows;
}, []);
return taskRows.map(this.renderTasksRow);
}
renderTasksRow(rowTasks) {
return <Row>{rowTasks.map(this.renderTask)}</Row>;
}
renderTask(task) {
const currentUserId = this.props.currentUser && this.props.currentUser._id;
const showPrivateButton = task.owner === currentUserId;
return (
<Task
key={task._id}
task={task}
showPrivateButton={showPrivateButton}
/>
);
}

Related

why map with condition return always value

I'm using rxjs map to retrive data in firestore like this:
getArtists(): Observable<DocumentData> {
const users$ = this.firestore.collection('/Users').get()
users$.subscribe((users) => {
users.docs.map(user => user.data().artistName !== "" && user.data().role === 'ARTIST')
});
return users$;
}
but when i'm getting value like this :
this.userService.getArtists().subscribe(
(userDocs) => {
userDocs.docs.map((user) => {
this.artists.push(user.data());
console.log(this.artists)
this.record = this.artists.length;
})
});
it's return always the user when the artistName is equals to "" and role is not equals to 'ARTIST'.
why ?
thank's everybody!
you need to map data in a map operator instead of a subscription and return a value in as a pipe.
Unfortunately, in your code isn't clear what and when you want to filter, why a user is in users.docs when it tend to be a doc.
Please check an example below and consider updating your question with more info.
import {filter, map} from 'rxjs/opreators';
getArtists(): Observable<DocumentData> {
return this.firestore.collection('/Users').get().pipe( // <- use pipe
map(users => {
// here some changes in users if we need.
return users;
}),
),
filter(users => {
returns true; // or false if we don't want to emit this value.
}),
}

get only changed objects from observed array with rxjs

I have an array of objects (not primitives) called "streaks" on my state tree and I want to observe only the changes to that array, not simply emit the entire array every time it changes. When I try this using pairwise() I get two identical arrays every time, even though I thought pairwise() would join the previous version and the current version. Why is pairwise() sending two identical arrays? NOTE streaks[1] and streaks[0] are identical, so _.differenceBy() isn't finding any changes because the two arrays are the same.
import {from} from "rxjs";
import {map, pairwise} from "rxjs/operators";
import * as _ from 'lodash';
const state$ = from(store);
const streaks$ = state$.pipe(
map(state => state.streaks),
// distinctUntilChanged(), <-- i've tried this and nothing is output at all
pairwise(),
map(streaks => {
let diff = _.differenceBy(streaks[0], streaks[1], _.isEqual);
console.log('diff', diff); //<-- this is an empty array
return diff;
})
);
streaks$.subscribe((streaksArray) => {
console.log('STREAKS$ 0', streaksArray); //<-- this is never even hit
} );
I solved this issue by creating an distinctUntilChangedArray operator that uses a self written compareArray function
Create compare array function
const compareArray<T> = (first: T[], second: T[], comparator=: (obj: T, obj2: T) => boolean): boolean {
return (first.length === 0 && second.length === 0)
|| (first.length === second.length && first.every((value, index) => {
return comparator
? comparator(value, second[index])
: JSON.stringify(value) === JSON.stringify(second[index]);
}))
}
Maybe you find a better array comparator. This is just my personal implementation of it
Create distinctUntilChangedArray operator
const distinctUntilChangedArray<T> = (comparator?: (prev: T, curr: T) => boolean): MonoTypeOperatorFunction<T[]> {
return distinctUntilChanged((prev: T[], curr: T[]) => {
return compareArray(first, second, comparator);
}
}
Final usage
interface nonPrimitive {
id: number;
name: string;
}
const nonPrimitiveComparator = (prev: nonPrimitive, curr: nonPrimitive): boolean => {
return prev.id === curr.id && prev.name === curr.name;
}
const source$: Observable<nonPrimitive>;
const distinctedSource$ = source$.pipe(
distinctUntilChangedArray(nonPrimitiveComparator)
);

Can't see my results in Ionic3 with SqLite, even though it recognizes number of rows

there, I'm new to Ionic and trying to learn my way with SQLite in it.
I get success in creating and droping tables, and after using INSERT INTO in a table I try to read its contents... That's when things get weird: I get a response like this:
{"rows":{"length":5},"rowsAffected":0}
Here's the code:
let sqlait: SQLite = new SQLite();
return sqlait.create({
name: 'contacomigo.db',
location: 'default'
}).then(
(db: SQLiteObject) => {
return db.executeSql('SELECT ' + Conta.col_id + ' FROM ' + Conta.tabela, {})
.then((data) => {
d.alert(JSON.stringify(data));
for (let i = 0; i < data.rows.length; i++) {
contas.push(data.rows.item(i));
}
})
.catch(e => d.alert(e));
}
).catch(e => { d.alert(e) });
if (contas.length == 0) {
contas.push('0 contas!');
} else {
d.alert(JSON.stringify(contas))
}
return contas.toString();
}
I would really love to learn that it's something ridiculous that I'm missing... Thanks in advance!
You have to fetch the results like this.
for (var i = 0; i < data[0].rows.length; i++) {
}

AngularFire2 Firebase Observable never ends (list is empty)

I'm trying to query an empty firebase list. The problem is that the observable method subscribe never finish and I can't show to user that ddbb list is empty.
The function getUserAppointmentsByDate(...) is calling getUserAppointments(...), where this.database.list('/appointment/users/' + user_uid) is an empty firebase list for the input user (user_uid).
how should I manage an empty query to firebase?
thanks in advance!
getUserAppointmentsByDate(user_uid: string, start: string, end: string) {
if (typeof (user_uid) == "undefined" || typeof (start) == "undefined" || typeof (end) == "undefined") {
console.error("invalid argument for getPatientReport");
return;
}
return this.getUserAppointments(user_uid)
.map(
(appointment) => {
return appointment
.filter((appointment) => {
var appointmentStart = new Date(appointment.start);
var startFilter = new Date(start);
var endFilter = new Date(end);
//Filter old, not cancelled and not deleted
return (appointmentStart.getTime() < endFilter.getTime())
&& (appointmentStart.getTime() > startFilter.getTime())
&& (appointment.status != AppointmentStatus.CANCELLED);
});
})
}
getUserAppointments(user_uid: string): any {
return this.database.list('/appointment/users/' + user_uid) //*THIS IS AN EMPTY LIST
.mergeMap((appointments) => {
return Observable.forkJoin(appointments.map(
(appointment) => this.database.object('/appointment/list/' + appointment.$key)
.take(1)))
})
}
As the this.database.list('/appointment/users/' + user_uid) return a empty array. Observable.forkJoin(appointments.map( complete without emit any value (that is the expected way of forkJoin works). In this case, you have two options, handling in the complete function.
.subscribe(
res => console.log('I got values'),
err => console.log('I got errors'),
// do it whatever you want here
() => console.log('I complete with any values')
)
or handle in an if statement:
import { of } from 'rxjs/observable/of';
...
return this.database.list('/appointment/users/' + user_uid)
.mergeMap((appointments) => {
if (appointments.length === 0) return of([]);
return Observable.forkJoin(appointments.map(
(appointment) => this.database.object('/appointment/list/' + appointment.$key)
.take(1)))
})

Redux reducer state not updating

import types from "../actions/types";
export default function(state = null, action) {
switch (action.type) {
case types.fetchCartProducts:
return action.payload || false;
case types.modifyCart:
debugger;
switch (action.payload.operation) {
case "subtract":
const index = action.payload.index;
let isSingleCount = state[index] === 1;
let chosenIds = state;
if (isSingleCount) {
chosenIds = chosenIds.filter(index => index != index);
} else {
[
...chosenIds.slice(0, index),
{ ...chosenIds[index], count: chosenIds[index].count - 1 },
...chosenIds.slice(index + 1)
];
}
return (
chosenIds
)
}
default:
return state;
}
}
{
"Products": [
{
index: 1,
name: "Shirt",
price: 1.9,
count: 2
},
{
index: 2,
name: "Jeans",
price: 1.9,
count: 2
}
]
}
I have a react component showing cart products. Each product in the cart is a seperate div and having + and - buttons to increase, decrease the no of that product. On - click I want to decrease the quantity and also if count is reduced to 0 I want to remove this product as well from my redux state.
Now I have my reducer where first I am checking if the count is 1 then removing the product itself else reducing the count only. I am returning the state but its not updating the DOM
Can anyone help in this am I doing something wrong in returning state.
Thanks
It looks like you are directly manipulating the state, which will cause problems in React. Instead of let chosenIds = state;, you should copy the state, let chosenIds = Object.assign({}, state);. Then you can manipulate chosenIds as you wish.
Looks like you forgot to include a assignment statement in the else block.
} else {
chosenIds = [
...chosenIds.slice(0, index),
{ ...chosenIds[index], count: chosenIds[index].count - 1 },
...chosenIds.slice(index + 1)
];
}
Instead of this complicated operation, you could use array.map to update a single item in the array.
chosenIds = state.map(item => item.index === index ? {...item, count: item.count - 1} : item)

Resources