l am trying to retrieve all data in a firebase database . When l used this code <h1>{{ item | async | json }}</h1> depending on doc of angularfire2 object l got list of json response object in html
{
"type": "value",
"payload": {
"8D3sENaBcLaXoGNnh1MPuoyj5LP2": {
"-LWl294Hs6YjkvJE5pqi": {
"name": "ddd",
"title": "dd"
},
"-LWlEonKLWfOttzirqp7": {
"name": "sas",
"title": "ass"
},
"-LWlGvn81Kes2A-1UcC2": {
"name": "asa",
"title": "asass"
},
"-LWlK92A7gaRkKVrZSFU": {
"name": "ddd",
"title": "ddd"
},
"-LWla1PYxsIFKhaCXvtu": {
"name": "ff",
"title": "fdsf"
},
"-LWpfRJP8VdwG927wyXS": {
"name": "ali",
"title": "ali"
},
"-LWph3ei12KTNyirdnZb": {
"name": "ddddd",
"title": "daD"
}
},
"WUM2HBkGo8TFDeOjEqO1s3lCj1p1": {
"-LWlHlhyS9m3ECS3wIdk": {
"name": "qwqsasasa",
"title": "as"
},
"-LWlHmXZAJdSPZurO7ii": {
"name": "qwqsasasa",
"title": "as"
},
"-LWph-fv4JMtTk22aE5X": {
"name": "sssssssssssssssssssssssss",
"title": "sssssssssssssssssssssssss"
}
}
},
"key": "report"
}
l want to get from this list json object only title and name . l used this code but l got empty page in html no data to show !
<h1>{{ (item | async)?.name }}</h1>
<h1>{{ (item | async)?.title }}</h1>
main code
itemRef: AngularFireObject<any>;
item: Observable<any>;
ionViewWillLoad(){
this.fire.authState.subscribe(data => {
if(data && data.email && data.uid){
this.toastCtrl.create({
message : ` welcome ${data.email}`,
duration:2000
}).present()
this.itemRef = this.db.object('report');
this.item = this.itemRef.snapshotChanges();
}
})
}
The /report key in your database seems to hold a list of objects: specifically a list of reports for each user, so with two nested keys under /report. But your code is loading it as a single object. This leads to this HTML <h1>{{ (item | async)?.name }}</h1> essentially displaying /report/name, which doesn't exist in your database.
If you want to display the name and title of a single report, you need to know the keys of that report. For example to show the first report for the first user:
this.itemRef = this.db.object('report/8D3sENaBcLaXoGNnh1MPuoyj5LP2/-LWl294Hs6YjkvJE5pqi');
The first subkey 8D3sENaBcLaXoGNnh1MPuoyj5LP2 here is the UID of the user whose report you're showing and the -LWl294Hs6YjkvJE5pqi is the first report of that user.
If you want to display all reports for a user, you will need to again know the key of the user and pass it into the database. But since you then get back a list of reports, you'll also need to use the list service from AngularFire and loop over the results in your HTML template, so that it generates the elements for each report:
this.reports = this.db.list('report/8D3sENaBcLaXoGNnh1MPuoyj5LP2');
And:
<ul>
<li *ngFor="let report of reports | async">
{{ item.title }} - {{ item.name }}
</li>
</ul>
If you want to display a nested list of all reports for all users, you'd start with the same as just above, but now load the data for all users, and use another ngFor to loop over the users first.
Also see:
the AngularFire documentation on lists
this tutorial on building a CRUD application with AngularFire
Related
I'm struggling to properly organize my Redux Store and my React components to properly deal with two-way nested data.
Suppose I have a post model and a user model. Let's take an abstracted example:
const user = {
"id": "1",
"name": "user 1",
"posts": [...] // list of post objects
}
const post = {
"id": "1",
"title": "post 1",
"user": user
}
The problem is that I cannot load this data like this because it will cause an infinite recursion error. I have to omit either the posts from the user or omit the user from the posts.
Here's what I ideally need:
I need to have a single post page that displays the post user with all his info (id, name) and the user's list of posts with the post info (id, title) in the same screen all at once.
I use normalizr to normalize the data.
How would I go about loading the data?
As per Redux docs (https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape) you should avoid nesting objects.
The solution here would be to treat the data like it is a database. That means that you should store ids instead of objects.
In your example:
const user = {
"id": "1",
"name": "user 1",
"posts": ["1", "2", ...] // list of post objects IDs
}
const post = {
"id": "1",
"title": "post 1",
"userId": "1"
}
Normally you would only save post_ids in the user, and user_id in the post. normalizer schemas can be configured to deal with those relations.
What is the incentive of adding the user key in post? Having shared data within two related data structures is redundant. The only data you should have in post is the relevant data and the minimum amount of information you need to properly associate the user with his/her posts. I would imagine you would want to have the string name of the user in post, or an id number of the user inside each post object
const user = {
"id": "1",
"name": "user 1",
"posts": [...] // list of post objects
}
const post = {
"id": "1",
"title": "post 1",
"user": "user 1"
}
EDIT:
From your comment, I would make an array of all users. But with a post key that is only the ids of posts that are associated with that user. And another array of only posts. As before, have an identifier to correlate the two. After that, parse your frontend on an as needed basis.
const users = [
{ name: 'andrew', id: 10, postIds: [1,3,23,30]},
// ...more users
]
const posts = [
{ name: 'a post', id: 23, userId: 10 }
{ name: 'another post', id: 3, userId: 10 }
{ name: 'a third post', id: 2, userId: 3 }
// ...more posts
]
Technically, userId is optional, but it can be a nice-to-have to be able to identify a user when inspecting individual posts
EDIT:
Wow, I just scrolled down and saw nordus has the exact same proposal, before me. While it's nice to see we're on the same page, make sure he/she gets credit if you like the idea ;).
I checked other question but they don't seem to solve my issue.
Here is my code :
var app = angular.module('myApp', []);
app.controller('listdata', function($scope, $http) {
$scope.users = [{
"name": "pravin",
"queue": [{
"number": "456",
"status": "Unavailable"
},
{
"number": "111",
"status": "Unavailable"
}],
"phone": "7411173737"
},
{
"name": "pratik",
"queue": [{
"number": "111",
"status": "Unavailable"
}],
"phone": "8558855858"
},
{
"name": "priyanka",
"queue": [{
"number": "456",
"status": "Unavailable"
}],
"phone": "5454573737"
},
{
"name": "prerana",
"queue": [{
"number": "111",
"status": "Unavailable"
}],
"phone": "7454543737"
}];
$scope.filter111 = function (user) {
return (user.queue.find(({number}) => number === '111'));
}
$scope.filter456 = function (user) {
return (user.queue.find(({number}) => number === '456'));
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.0/angular.min.js"></script>
<div ng-app="myApp">
<label class="switch">
<input type="checkbox" ng-model="queue111">111
</label>
<label class="switch">
<input type="checkbox" ng-model="queue456">456
</label>
<div class="row" ng-controller="listdata">
<div ng-repeat="user in users|filter: queue111? filter111: ''|filter: queue456? filter456: ''">
<p> {{user.name}} {{user.phone}}</p>
</div>
</div>
</div>
I have created custom functions $scope.filter111 and $scope.filter456 respectively to filter data
Currently when I click the checkbox 111, the filter return only the record whose queue has a number 111 and when I click the checkbox 456, the filter returns only the records whose queue has a number 456. This much is working perfectly. When I click both the filters it displays only that object whose queue has both the number 111 and 456 i.e an AND operation is occurring here.
Expected result : I want it such that when I click both the checkbox
it should display all the records from 111 as well as 456 together i.e an OR operation.
How do I do this?
You can try creating a custom angularJS filter by referring w3schools.com example and this link (for better understanding of custom filters).
In your case, the custom angularjs filter would take 3 inputs, i.e the list you want to filter and the value of the checkboxes- queue111 and queue456. Perform filtering and returning the data by providing necessary conditions based on the value of checkboxes inside the filter.
This also reduces the code that you use in your HTML for filtering inside ng-repeat from
<div ng-repeat="user in users|filter: queue111? filter111: ''|filter: queue456? filter456: ''">
<p> {{user.name}} {{user.phone}}</p>
</div>
to
<div ng-repeat="user in users|customFilter: queue111:queue456">
<p> {{user.name}} {{user.phone}}</p>
</div>
where
customFilter is the name (can be any name, provided that name as
an example) of the angularJS filter you create.
users will be the default first input of your custom filter and the value of your checkboxes will be the 2nd and 3rd input respectively.
Also, it would be helpful if you provide codepen/plunker demos so that people can debug your problem and provide solutions easily.
I haven't found a solution online to this yet, if its available i would love to check it out. I would like to be able to create dynamic checkboxes based on selection from a dropdown, basically the dropdown looks something like this
<select>
<option value="Computer">Volvo</option>
<option value="Vehicle">Saab</option>
</select>
I have an accessories table in the database storing accessories that should be displayed to the user.
id | category | name |
----------------------------
1 | computer | mouse |
2 | computer | keyboard |
2 | vehicles | Roof-rack |
I would like to have a scenario where the user selects a category in the dropdown then a group of check boxes are dynamically created based on the name of accessories in the table. I'm using the code below that should return
a JSON of accessory names.
$.get("{{config('app.url') }}/hardware/models/"+catid+"/accesories",{_token: "{{ csrf_token() }}"},function (data) {
});
EDIT: the data returned looks somethink like;
{
"computer": [{
"id": "1",
"name": "mouse"
},
{
"id": "2",
"name": "keyboard"
},
{
"id": "1",
"name": "mouse"
}
]
}
For example: if a user selects computer from the dropdown then there should be checkboxes of accessories like keyboard, mouse, etc generated dynamically. Hope you can help me out. I am using laravel if that's important. Thanks
It will be better to return an array of objects instead, then you could iterate every accessory and generate the proper related checkbox like the following example shows :
$.get("{{config('app.url') }}/hardware/models/"+catid+"/accesories",{_token: "{{ csrf_token() }}"},function (data) {
data = $.parseJSON(data);
data.forEach( function (obj){
$('#dynamic_div').append('<input name="accesories" type="checkbox" value="'+obj.id+'"/> '+obj.name +'<br/>');
});
});
NOTE : If you cant' change the returned result you could change just the parse line to :
data = $.parseJSON(data['computer']);
But you should take in your consideration that 'computer' should be changed dynamically as a variable.
Hope this helps.
var arr = [{
"id": "1",
"name": "mouse"
},
{
"id": "2",
"name": "keyboard"
},
{
"id": "1",
"name": "mouse"
}
];
arr.forEach( function (obj)
{
$('#dynamic_div').append('<input name="accesories" type="checkbox" value="'+obj.id+'"/> '+obj.name +'<br/>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dynamic_div"></div>
so I'm working with a basic product category model to get my head around filtering and I can't figure out how to extract a property value from one object within an array while repeating through another.
A simplified version of my category array, which is in scope, looks like this. I can output their names with the preceding directive and the results are as expected:
[{
"_id": "TY76",
"name": "Planes"
}, {
"_id": "887T",
"name": "Trains"
}, {
"_id": "A0K4",
"name": "Autos"
}]
<p ng-repeat="category in product.categories "> {{ category.name }}</p>
And here is a simplified product, also in scope, which may contain the ID of one or more categories. In this case, Bobble Head belongs to both Planes and Autos:
{
"_id": "9876",
"name": "Bobble Head",
"cats": "['TY76','A0K4']"
}
Now, here is where I'm having a hard time. I need to output the category names with the product. I can output the IDs no problem via:
<p ng-repeat="cat in product.cats ">{{ cat }}</p>
But that's of no use to the end user but I have no idea how to end up with something like:
Product: Bobble Head | Categories: Planes, Autos
I don't have the autonomy to add the category name to each product and I've tried a bunch of different filtering approaches but I don't think I'm wording my question right or something because I'm not finding much on the interwebs about this.
Any ideas?
Sounds like you want to build up a lookup for category id to category name:
var categories = [{
"_id": "TY76",
"name": "Planes"
}, {
"_id": "887T",
"name": "Trains"
}, {
"_id": "A0K4",
"name": "Autos"
}];
// build a category lookup id -> name
var categoryLookup = {};
categories.forEach(function(category) {
categoryLookup[category._id] = category.name;
});
Here's a full working fiddle: http://jsfiddle.net/02qadem7/1/
You can create a key-pair object where the key is the id and the value is the name of the category:
var categoriesArray = [{
"_id": "TY76",
"name": "Planes"
}, {
"_id": "887T",
"name": "Trains"
}, {
"_id": "A0K4",
"name": "Autos"
}];
$scope.categoriesMap = {};
categoriesArray.forEach(function(category) {
$scope.categoriesMap[category._id] = category.name;
});
Then in your view you can access the category name like this:
<div ng-repeat="product in products">
<strong>Product: </strong> {{product.name}} |
<strong>Categories: </strong> <span ng-repeat="category in product.cats">
{{categoriesMap[category]}}
</span>
</div>
Here's a plunkr: http://plnkr.co/edit/BpBcCizzU2Vh8VPniiHA?p=preview
I sugest using a custom filter on categories array.
myApp.filter('byCategoryIds', function() {
return function(categories, catIds) {
return categories.filter(function(item) {
return (catIds.indexOf(item._id) != -1);
});
};
});
Then you can iterate on categori array sending ids array like so:
<b>Product:</b>
{{product.name}};
<b>Categories:</b>
<span ng-repeat="cat in categories | byCategoryIds: product.cats">{{ cat.name }}, </span>
I am trying to follow this example on how to setup a combo-box using dojo, but wondering how one can specify name and value programmatically. The example presented uses the same values for label and value - which is probably not one wants in most cases.
{
"identifier": "abbreviation",
"label": "name",
"items": [
{ "abbreviation": "AL", "name": "Alabama" },
... other 48 states here ...
{ "abbreviation": "WY", "name": "Wyoming" }
]
}
If you are asking how to replace the hard coded list in the example then here is what you have to do. In the above scenario items was used to specify the data which is an array (abbreviations and names) of values.
In your case you will need to get the data / object from your data source. Once you have that data/object expose it to the view. Once this has been done you can now do the following structure.
You store is really your items above however stateStore will be a java script array which contains the data from your data source.
stateStore = [{"abbreviation": "AL", "name": "Alabama"},
... other 48 states here ...,
{ "abbreviation": "WY", "name": "Wyoming" }]
// create FilteringSelect widget, populating its options from the store
var select = new dijit.form.FilteringSelect({
name: "stateSelect",
placeHolder: "Select a State",
store: stateStore
}, "stateSelect");
HTML
<div style="width:50%;float: left;">
<h1>dijit.form.Select</h1>
<label for="stateSelect">State:</label>
<div id="stateSelect"></div>
</div>