I have five pages with different state. The first page contains object with the format
{
"good": {
"good1": "good",
"good2": "good",
"good3": "good"
},
"bad": {
"bad1": "bad",
"bad2": "bad",
"bad3": "bad"
},
"excellent": {
"excellent1": "excellent",
"excellent2": "excellent",
"excellent3": "excellent"
}
}
this object is saved to localstorage.
This is my codepen where i have tried to show what i really want.The scenario is , good1 value is going to be looping through 4 pages and next time redirect to first page with the next value(ie good2 ) and the next value also goes through the same 4 pages and so on. What i have to do to solve this problem? if i am doing wrong with the object structure, what should be the good approach?
I would recommend that you put your data into a service, then it will be much easier to share it between pages, persist it to local storage and retrieve it.
.factory('amazingData',function() {
var ohYeah = {
'good':{
'good1':'good',
'good2':'good',
'good3':'good'
},
'bad':{
'bad1':'bad',
'bad2':'bad',
'bad3':'bad'
},
'excellent':{
'excellent1':'excellent',
'excellent2':'excellent',
'excellent':'excellent'
}
};
return ohYeah;
})
Now you can use this service and inject it into your controllers:
.controller('homeCtrl',function($scope, amazingData){
$scope.data=amazingData;
})
.controller('pageCtrl',function($scope, amazingData){
$scope.data=amazingData;
})
The data will be the same for all pages.
Related
In my React/JS project, user checkes one or more of 3 option which user wants to see that type of data . These data types are final, generation, and availability. All of these 3 data types has different url's. I need to send request these data types which are checked in the form, I will not send the request to the unchecked one. I need a logic to check which one is selected and which one is unselected. I'm holding these data type states in an array named datatypes like this.
{
"id":"final",
"isChecked": false
},
{
"id":"generation",
"isChecked": false
},
{
"id":"availability",
"isChecked": false
}
]
I'm changing the state of isChecked property true, or false. And finally ı need to make a check and send request the isChecked= true ones. But ı dont want to do this operation like this:
**if**(datatypes[0].isChecked===**true** && datatypes[1].isChecked===**true** && datatypes[0].isChecked===**true**){
//request for 3 of data type
}
**else if**(datatypes[0].isChecked===**true** && datatypes[1].isChecked===**true** && datatypes[0].isChecked===**false**){
//request for first two data type(final, generation) and not for the 3. one
}
**else if**()...
It is exactly not the correct way to make this check. so what is the best and short logic for this situation? I'll be really greatful for every help and advice,
Thx in advance :)
I think you're asking about how to filter the list of possibilities into an actionable list of only the checked options. This is basically a filter then map operation as shown below.
const possibilities = [
{
"id":"final",
"isChecked": false
},
{
"id":"generation",
"isChecked": false
},
{
"id":"availability",
"isChecked": false
}
]
// if you need to do a single request for each checked option
function doMyRequest(option: string) {
...your request code here
}
possibilities
.filter(possibility => possibility.isChecked)
.forEach(possibility => doMyRequest(possibility));
// or if you need to do one request with all checked options
function doMyRequest(options: string[]) {
...your request code here
}
doMyRequest(
possibilities
.filter(possibility => possibility.isChecked)
.map(possibility => possibility.id)
);
What I am trying to do
I am creating a social media app with react native and firebase. I am trying to call a function, and have that function return a list of posts from off of my server.
Problem
Using the return method on a firebase query gives me a hard to use object array:
Array [
Object {
"-L2mDBZ6gqY6ANJD6rg1": Object {
//...
},
},
]
I don't like how there is an object inside of an object, and the whole thing is very hard to work with. I created a list inside my app and named it items, and when pushing all of the values to that, I got a much easier to work with object:
Array [
Object {
//...
"key": "-L2mDBZ6gqY6ANJD6rg1",
},
]
This object is also a lot nicer to use because the key is not the name of the object, but inside of it.
I would just return the array I made, but that returns as undefined.
My question
In a function, how can I return an array I created using a firebase query? (to get the objects of an array)
My Code
runQ(group){
var items = [];
//I am returning the entire firebase query...
return firebase.database().ref('posts/'+group).orderByKey().once ('value', (snap) => {
snap.forEach ( (child) => {
items.push({
//post contents
});
});
console.log(items)
//... but all I want to return is the items array. This returns undefined though.
})
}
Please let me know if I'm getting your question correctly. So, the posts table in database looks like this right now:
And you want to return these posts in this manner:
[
{
"key": "-L1ELDwqJqm17iBI4UZu",
"message": "post 1"
},
{
"key": "-L1ELOuuf9hOdydnI3HU",
"message": "post 2"
},
{
"key": "-L1ELqFi7X9lm6ssOd5d",
"message": "post 3"
},
{
"key": "-L1EMH-Co64-RAQ1-AvU",
"message": "post 4"
}
...
]
Is this correct? If so, here's what you're suppose to do:
var items = [];
firebase.database().ref('posts').orderByKey().once('value', (snapshot) => {
snapshot.forEach((child) => {
// 'key' might not be a part of the post, if you do want to
// include the key as well, then use this code instead
//
// const post = child.val();
// const key = child.key;
// items.push({ ...post, key });
//
// Otherwise, the following line is enough
items.push(child.val());
});
// Then, do something with the 'items' array here
})
.catch(() => { });
Off the topics here: I see that you're using firebase.database().... to fetch posts from the database, are you using cloud functions or you're fetching those posts in your App, using users' devices to do so? If it's the latter, you probably would rather use cloud functions and pagination to fetch posts, mainly because of 2 reasons:
There might be too many posts to fetch at one time
This causes security issues, because you're allowing every device to connect to your database (you'd have to come up with real good security rules to keep your database safe)
Sorry if this was answered elsewhere, I tried to search but I'm not even sure what I'm looking for.
Let say I have this object to work with:
userRequest: {
id: number,
subject: string,
...
orderIds: number[]
...
}
order: {
id: number,
...
clientId: number,
productIds: number[]
}
client: {
id: number,
name: string,
...
}
product: {
id: number,
name: string,
price: number
}
Now, at some point the user will fill a form using that composite object and send it for analysis. But before sending it, it has first to be validated. And I cannot validate in the form because the user is simply entering the data received on paper. If the data is "invalid", a request for more information will be sent.
So, I need to validate the request, but also the order, the products and the client. I am requested to show a "Validating Request" screen and after each element was checked, a "Valid" or "Invalid" screen. Simple enough.
But now, I'm sending http requests and get Observables to deal with. I'm trying to learn more about them and all the available operators and how to mix them, but at the moment, I'm completely lost.
So, I first get an Observable<userRequest> from server. Then, once I get a userRequest, I need to get all the orders from their id's, and when I get an "order", I have to get the client & his products.
All this is done asynchronously, but I cannot get the client or the products until I receive the order, and I need the userRequest to provide the orders. In addition, when I get an order, I need to get both the client AND the products at the "same time" since they both need the same order...? For the grand finale, for every element I get (request, order, client, product) I need to validate it and wait for every element to say "the request is valid" or not.
So to resume:
I need to get an Observable<userRequest> and validate
Now, I have to get an Observable<order[]> and validate each order
For each order, I have to 1) get an Observable<Client> and validate PLUS 2) get an Observable<Product[]> and validate each one
Wait for every observables to complete and check if it's valid or not
Steps 1 and 2 needs to be executed sequentially, but when step 2 completes, I need to execute steps 3.1 and 3.2 for each result of step 2. And wait.
I'm sure it's far from clear, I just hope it clear enough so you guys gets want I want to achieve. If you have any hints for me, please do share!!! ; )
Edit
I do know somehow what needs to be done. But where I lose my cool, is when I need to chain the Observables sequentially (as each one depends on the one before), at various point I need to call a validation method and when it comes to the Client and the Products, both need the Order for it's Id. I did try many, many ways but I just don't grasp the concept completely.
bygrace - No, I don't want the validation to block. It should validate everything as it will result in a request for all the missing or invalid parts, and it should be showed at the end. That why I need a way to know when everything is done so I can check if errors were found.
The request, orders, client and products each comes from their respective services. The service makes an http resquest and returns an Observable. So I need to chain the calls (and when it comes to the Order, I need to get TWO Observables for the same Order Id).
QuietOran - Here's something I tried. It's horrible I know, but I'm so lost right now...
onValidateRequest(requestId: number) {
this.requestService.getUserRequest$(this.requestId)
.do(request => {
this.validateRequest(request);
})
.concatMap(request => this.orderService.getOrdersForRequest$(request.id))
.do(orders => {
this.validateOrders(orders);
})
.concatMap(orders => {
// Now, this is were I'm completely lost
// I manage to get the request and the orders, but in this block, I need to get the client AND the products
// and validate each one as I receive it
// Then return something
})
.do(() => {
// when I validate an element, if there's an error, I simple add it in an array.
// So when ALL the Observable above are completed, this function simply checks
// if there's something in it
this.checkForErrors();
})
.subscribe();
}
I'm going to give you something rough that you can refine with feedback because I'm not clear on the final shape of the data you want back and all. Hopefully this points you in the right direction.
Basically if you want the data from one observable to feed another then you can use switchmap or one of its cousins. If you need the value fed in as well as the result then just lump them together with a combineLatest or something similar.
console.clear();
function getUserRequest(requestId) {
return Rx.Observable.of({ id: 1, subject: 'a', orderIds: [10, 20] })
.delay(500).take(1);
}
function getOrdersForRequest(requestId) {
return Rx.Observable.of([
{ id: 10, clientId: 100, productIds: [ 1000 ] },
{ id: 20, clientId: 200, productIds: [ 1001, 1002 ] }
]).delay(200).take(1);
}
function getClientForOrder(orderId) {
let client;
switch(orderId) {
case 10:
client = { id: 100, name: 'Bob' };
break;
case 20:
client = { id: 200, name: 'Alice' };
break;
}
return Rx.Observable.of(client).delay(200).take(1);
}
function getProductsForOrder(orderId) {
let products;
switch(orderId) {
case 10:
products = [{ id: 1000, name: 'p1', price: 1 }];
break;
case 20:
products = [
{ id: 1001, name: 'p1', price: 2 },
{ id: 1002, name: 'p1', price: 3 }
];
break;
}
return Rx.Observable.of(products).delay(200).take(1);
}
Rx.Observable.of(1)
.switchMap(id => Rx.Observable.combineLatest(
getUserRequest(id),
getOrdersForRequest(id)
.switchMap(orders => Rx.Observable.combineLatest(
Rx.Observable.of(orders),
Rx.Observable.combineLatest(...orders.map(o => getClientForOrder(o.id))),
Rx.Observable.combineLatest(...orders.map(o => getProductsForOrder(o.id)))
)
),
(userRequest, [orders, clients, products]) =>
({ userRequest, orders, clients, products })
)
).subscribe(x => { console.dir(x); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>
Right now I flattened the results by category. You may want them nested or something like that. This is just a rough pass so provide feedback as needed.
I use Meteor to query a mongo collection. It has for example the following entry:
{
"_id": "uCfwxKXyZygcWQeiS",
"gameType": "foobar",
"state": "starting",
"hidden": {
"correctAnswer": "secret",
"someOtherStuff": "foobar"
},
"personal": {
"Y73uBhuDq2Bhk4d8W": {
"givenAnswer": "another secret",
},
"hQphob8s92gbEMXbY": {
"givenAnswer": "i have no clue"
}
}
}
What I am trying to do now is:
don't return the values behind "hidden"
from the "personal" embedded document only return the values for the asking user
In code it would look something like this:
Meteor.publish('game', function() {
this.related(function(user) {
var fields = {};
fields.hidden = 0;
fields.personal = 0;
fields['personal.' + this.userId] = 1;
return Games.find({}, {fields: fields});
}, Meteor.users.find(this.userId, {fields: {'profile.gameId': 1}}));
}
Obviously this won't work, because MongoDB won't allow mixed includes and excludes. On the other hand, I cannot switch to "specify only the included fields", because they can vary from gameType to gameType and it would become a large list.
I really hope that you can help me out of this. What can I do to solve the problem?
Typical example of where to use the directly controlled publication features (the this.added/removed/changed methods).
See the second example block a bit down the page at http://docs.meteor.com/api/pubsub.html#Meteor-publish.
With this pattern you get complete control of when and what to publish.
The image shows the structure of my database.
I want to print 1, 2 ... (so on) i.e. the parent element names alone. But couldn't understand how to do that.
The Firebase Database is essentially one JSON object.
This object is in a tree structure. If you read from one location in the tree, you'll get each piece of data underneath it.
Take a look at this sample database.
{
"items": {
"1": {
"title": "Hi"
},
"2": {
"title": "Bye"
}
}
}
There is no way with the JavaScript SDK or AngularFire, to only read the parent keys of 1 and 2 under "items".
If you only want to read the parent keys, you'll need to create an index for them in the Firebase database.
{
"items": {
"1": {
"title": "Hi"
},
"2": {
"title": "Bye"
}
},
"itemKeys": {
"1": "Hi",
"2": "Bye"
}
}
Now you can create a reference at the itemKeys location and pass that to a $firebaseArray() or $firebaseObject().
var ref = new Firebase('<my-firebase-app>.firebaseio.com/itemKeys');
var syncArray = $firebaseArray(ref);
If you're concerned with keeping two separate data structures consistent, check out the client-side fan-out feature.
shallow=true
If you are using REST API add this to the end of your request url. Like this
https://docs-examples.firebaseio.com/rest/retrieving-data.json?shallow=true