Data Structure for Restaurant Menu NoSQL(firebase) - database

I am trying to make a restaurant menu that will be like:
final menu = {
'Pizza': [
{
'name': 'Hawaiian Pizza',
'imageDownloadUrl': 'https://~',
'description': 'Amazing combination of pineapple and ham',
'price': 12.99,
'options': {'extraHam': true, 'extraPinapple': true},
},
{
'name': 'Pepporoni Pizza',
'imageDownloadUrl': 'https://~',
'description': 'Amazing combination of pepporoni and ham',
'price': 14.99,
'options': {'extraCheese': true, 'extraPinapple': 2},
},
],
'Hamburger' : [
{
'name': 'CheeseBurger',
'imageDownloadUrl': 'https://~',
'description': '~',
'price': 4.99,
'options': {'extraHam': true, 'extraPinapple': true},
},
{
'name': 'Vegan Burger',
'imageDownloadUrl': 'https://~',
'description': '~',
'price': 6.99,
'options': {'extraCheese': true, 'extraPinapple': 2},
},
]
};
I would like to put this under the shop document so that I can fetch when the shop is fetched. However, I would like to give each menu unique ID so that I can use the menu in the other side of app. How should I implement this?
Should I make a collection('menus') and give the shop ID to the document and put the data as a field?
I am new to NoSQL(firebase) and it's just so hard for me to work on this.
Please help me. Thank you!

Related

How to construct multiple dictionaries to array in react native

I am trying to show Expand/Collapse Flatlist data in react-native.
It is like single parent with multiple childs. So, If user tap on the cell, I have to show multiple rows for that expand/collapse.
But, I am getting data from server like following.
[{
code: '1212',
name: 'Bajaj Model 1',
url: 'Some url',
category: 'Bike'
},
{
code: '1213',
name: 'Bajaj Model 2',
url: 'other url',
category: 'Bike'
},
{
code: '1454',
name: 'BMW Model 1',
url: 'Some url',
category: 'Car'
},
{
code: '1454',
name: 'BMW Model 2',
url: 'Some url',
category: 'Car'
}
]
So, All the Bike data, I have to show one place like Parent and child.
For that I have done filter.
const fundsFilterData = mapValues(groupBy(response, 'category'),
fundslist => fundslist.map(item => omit(item, 'category')));
And I am getting like following.
{
'Bike': [{
code: '1212',
name: 'Bajaj Model 1',
url: 'Some url'
},
{
code: '1213',
name: 'Bajaj Model 2',
url: 'other url'
},
],
'Car': [{
code: '1454',
name: 'BMW Model 1',
url: 'Some url'
},
{
code: '1454',
name: 'BMW Model 2',
url: 'other url'
},
]
}
But, I want to make it as array along with some pre added keys like following.
[{
'Title': 'Bike',
'Values': [{
'code': '1212',
'name': 'Bajaj Model 1',
'url': 'Some url'
},
{
'code': '1454',
'name': 'Bajaj Model 2',
'url': 'other url'
}
]
},
{
'Title': 'Car',
'Values': [{
'code": '
1454 ',
'name": '
BMW Model 1 ',
'url": '
Some url '
},
{
'code': '1454',
'name': 'BMW Model 2',
'url': 'Some url'
}
]
}
}
So that I can show Titles in headers and once user tap on row, I can show child's data as expanded.
Any suggestions?
Use _.map() which returns an array, and not _.mapValues(). In the _.map() get the Title (the key) from the 2nd param. Use it and the values (after _.omit()) to construct an object for each group.
const { map, groupBy, omit } = _;
const response = [{"code":"1212","name":"Bajaj Model 1","url":"Some url","category":"Bike"},{"code":"1213","name":"Bajaj Model 2","url":"other url","category":"Bike"},{"code":"1454","name":"BMW Model 1","url":"Some url","category":"Car"},{"code":"1454","name":"BMW Model 2","url":"Some url","category":"Car"}];
const fundsFilterData = map(
groupBy(response, 'category'),
(list, Title) => ({
Title,
Values: list.map(item => omit(item, 'category'))
})
);
console.log(fundsFilterData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

ag-grid grouping not adding expand/collapse controls

I'm trying to show some data that is grouped using ag-grid. The data is being displayed correctly, but it is not grouping the data as it should. I'm using angularJS 1.5.8 and ag-grid 12.0.2. Here is a very simplified version of what I'm trying to do:
function _setGridOptions() {
var data = [
{packageID: "one", documentID: "one-one", cost: 1},
{packageID: "one", documentID: "one-two", cost: 2},
{packageID: "one", documentID: "one-three", cost: 3},
{packageID: "two", documentID: "two-one", cost: 4},
{packageID: "two", documentID: "two-two", cost: 5},
{packageID: "two", documentID: "two-three", cost: 6}
];
var cols = [
{
headerName: "Package ID",
width: 100,
field: "packageID",
rowGroup: true
},
{
headerName: "Document ID",
width: 100,
field: "documentID"
},
{
headerName: "Cost",
width: 100,
field: "cost"
}
];
$ctrl.agGridOptions = {
columnDefs: cols,
animateRows: true,
enableRangeSelection: true,
rowData: data,
enableSorting: true,
debug: true,
enableColResize: true,
onGridReady: function () {
$ctrl.agGridOptions.api.sizeColumnsToFit();
}
};
$ctrl.transactionsLoaded = true;
}
And here is what the table looks like:
As you can see there is no "Group" column and there is no expand/collapse control by the group row.
Any ideas what I'm doing wrong?
I just realized what the issue is. The "Grouping Rows" feature is an enterprise feature and I am using the free version.
Actually it is not an Enterprise feature, but it is a free version feature that everyone can use this. Even tree-data feature is can be used with free version how ever only some of extra features are under Enterprise version of Ag-grid. Maybe in the date of question, Row Grouping was available for Enterprise version, I don't know. Now, it is free all.
Although the question is very historical for our field, I will share an answer because of those who are in need to use row grouping Ag-grid in any version.
Actually, your data and your gridOptions definition is quite enough to enable row grouping, to be clear, however the version of Ag-grid you used was very older. If someone take your data and use newer version of Ag-grid, he/she can see that you data is providing the requirement of row grouping.
In short, to applying a row grouping, it is sufficient to declare rowGroup: true in the definition of the column which we want to apply.
gridOptions.columnDefs = [
{ field: "country", rowGroup: true },
{ field: "sport", rowGroup: true },
];
And the data is:
rowData= [
{ 'country': 'United States', 'sport': 'Biking' },
{ 'country': 'United States', 'sport': 'Swimming', },
{ 'country': 'United States', 'sport': 'Swimming' }
{ 'country': 'Turkey', 'sport': 'Swimming', },
{ 'country': 'Turkey', 'sport': 'Swimming' }
{ 'country': 'Brasil', 'sport': 'Football' }
]
More detail, see page: ag-grid.com/javascript-grid-grouping

UI-GRID Dynamic column headers and array of object data

I have following data
vm.myData =
{
'Type' :
[
'A',
'B',
'C'
],
'Data': [
{
'Key': 'XXX',
'AValues':
{
'ID': '1',
'Val': '10'
},
'BValues':
{
'ID': '2',
'Val': '20'
},
'CValues':
{
'ID': '2',
'Val': '20'
}
},
{
'Key': 'TTT',
'AValues':
{
'ID': '2',
'Val': '30'
},
'BValues':
{
'ID': '4',
'Val': '70'
},
'CValues':
{
'ID': '2',
'Val': '20'
}
}
]
};
I am trying to show data as below
Key A B C
XXX 10 20 20
TTT 30 70 20
I tried it many ways but not able to get desired result.
I want the name of the Columns to come from 'Type' on 'myData'.
I am able to display first row by hardcoding.
vm.gridOptions = {
columnDefs: [
{ name: 'Key', field: 'Data[0].Key'},
{ name: 'A', field: 'Data[0].AValues.Val'},
{ name: 'B', field: 'Data[0].BValues.Val'},
{ name: 'C', field: 'Data[0].CValues.Val'}
],
data: vm.myData
};
I would really appreciate any help.
Update
After going through Naren Mulrali's suggestion, I did following which gives me desired result.
But I have hardcoded column names(I need different display names).
Is there a way to dynamically get column header from the 'Type' array from 'myData'
vm.gridOptions = {
columnDefs: [
{ displayName: 'Key', name: 'Key' },
{ displayName: 'A', name: 'AValues.Val' },
{ displayName: 'B', name: 'BValues.Val' },
{ displayName: 'C', name: 'CValues.Val' }
],
data: vm.myData.Data
};
You need to convert your Object into a format that angular ui grid understands, please refer to the below JSFiddle
angular.forEach($scope.myData.Data, function(value, index){
value.AValues = value.AValues.Val;
value.BValues = value.BValues.Val;
value.CValues = value.CValues.Val;
$scope.myData.Data[index] = value;
});
JSFiddle: link

Use variable in another variable in Angular?

i'm trying to use this component
https://github.com/alexklibisz/angular-dual-multiselect-directive
but I don't know how could I pass data from the back-end to the component.
I get the data from the back-end:
var vm = this;
vm.Categoria1 = [];
$http.get('http://localhost:5541/api/date/ListCategorii').success(function (data) {
vm.Categoria1 = data;
}
);
I get the data:
[{"Id":1,"NumeCategorie":"Fructe"},{"Id":2,"NumeCategorie":"Legume"},{"Id":3,"NumeCategorie":"Ciocolata"}]
but below vm.Categoria1 is empty:
$scope.demoOptions = {
title: 'Demo: Recent World Cup Winners',
filterPlaceHolder: 'Start typing to filter the lists below.',
labelAll: 'All Items',
labelSelected: 'Selected Items',
helpMessage: ' Click items to transfer them between fields.',
/* angular will use this to filter your lists */
orderProperty: 'name',
/* this contains the initial list of all items (i.e. the left side) */
items: vm.Categoria1, //[{ 'id': '50', 'name': 'Germany' }, { 'id': '45', 'name': 'Spain' }, { 'id': '66', 'name': 'Italy' }, { 'id': '30', 'name': 'Brazil' }, { 'id': '41', 'name': 'France' }, { 'id': '34', 'name': 'Argentina' }],
/* this list should be initialized as empty or with any pre-selected items */
selectedItems: []
};
Thank you.
The best practice is to use like this :
var vm = this;
vm.Categoria1 = [];
$http.get('http://localhost:5541/api/date/ListCategorii')
.success(function(data) {
vm.Categoria1 = data;
$scope.demoOptions = {
title: 'Demo: Recent World Cup Winners',
filterPlaceHolder: 'Start typing to filter the lists below.',
labelAll: 'All Items',
labelSelected: 'Selected Items',
helpMessage: ' Click items to transfer them between fields.',
/* angular will use this to filter your lists */
orderProperty: 'name',
/* this contains the initial list of all items (i.e. the left side) */
items: vm.Categoria1, //[{ 'id': '50', 'name': 'Germany' }, { 'id': '45', 'name': 'Spain' }, { 'id': '66', 'name': 'Italy' }, { 'id': '30', 'name': 'Brazil' }, { 'id': '41', 'name': 'France' }, { 'id': '34', 'name': 'Argentina' }],
/* this list should be initialized as empty or with any pre-selected items */
selectedItems: []
})
.error(function(data, status) {
console.error('Repos error', status, data);
})
.finally(function() {
console.log("finally finished repos");
});
Hope that helps ! Sa-mi spui daca ai probleme.
You need to set demoOptions in the success callback:
var vm = this;
vm.Categoria1 = [];
$http.get('http://localhost:5541/api/date/ListCategorii').success(function (data) {
vm.Categoria1 = data;
$scope.demoOptions = {
title: 'Demo: Recent World Cup Winners',
filterPlaceHolder: 'Start typing to filter the lists below.',
labelAll: 'All Items',
labelSelected: 'Selected Items',
helpMessage: ' Click items to transfer them between fields.',
/* angular will use this to filter your lists */
orderProperty: 'name',
/* this contains the initial list of all items (i.e. the left side) */
items: vm.Categoria1, //[{ 'id': '50', 'name': 'Germany' }, { 'id': '45', 'name': 'Spain' }, { 'id': '66', 'name': 'Italy' }, { 'id': '30', 'name': 'Brazil' }, { 'id': '41', 'name': 'France' }, { 'id': '34', 'name': 'Argentina' }],
/* this list should be initialized as empty or with any pre-selected items */
selectedItems: []
};
});
Other option is, you can create one function contains that http.get
call and call that function on page load :
var vm = this;
vm.Categoria1 = [];
var onload = function(){
$http.get('http://localhost:5541/api/date/ListCategorii').success(function (data) {
vm.Categoria1 = data;
}
};
$scope.demoOptions = {
title: 'Demo: Recent World Cup Winners',
filterPlaceHolder: 'Start typing to filter the lists below.',
labelAll: 'All Items',
labelSelected: 'Selected Items',
helpMessage: ' Click items to transfer them between fields.',
/* angular will use this to filter your lists */
orderProperty: 'name',
/* this contains the initial list of all items (i.e. the left side) */
items: vm.Categoria1, //[{ 'id': '50', 'name': 'Germany' }, { 'id': '45', 'name': 'Spain' }, { 'id': '66', 'name': 'Italy' }, { 'id': '30', 'name': 'Brazil' }, { 'id': '41', 'name': 'France' }, { 'id': '34', 'name': 'Argentina' }],
/* this list should be initialized as empty or with any pre-selected items */
selectedItems: []
};
onload();
You should set the items in the request success :
$http.get('http://localhost:5541/api/date/ListCategorii')
.success(function (data) {
$scope.demoOptions.items = vm.Categoria1 = data;
});

ExtJS 4 MVC accordion with dynamic clickable contents from json

I need up insert/add child panels to an accordion. Each of these child panels should have it's title using 'field' value in the data (see below), and the contents of each child should be (labels or a displayfield or ??) as long as it's clickable. The json data from the server is as below:
data: [{
'field': 'cities',
'values': [{
'value': 'DC',
'count': 5
}, {
'value': 'SF',
'count': 2
}, {
'value': 'NYC',
'count': 4
}, {
'value': 'Nashville',
'count': 4
}]
}, {
'field': 'beaches',
'values': [{
'value': 'obx',
'count': 1
}, {
'value': 'ocean city',
'count': 2
}, {
'value': 'myrtle',
'count': 4
}]
}, {
'field': 'planets',
'values': [{
'value': 'mercury',
'count': 1
}, {
'value': 'venus',
'count': 2
}, {
'value': 'earth',
'count': 4
}, {
'value': 'mars',
'count': 1
}, {
'value': 'jupiter',
'count': 2
}, {
'value': 'uranus',
'count': 4
}, {
'value': 'neptune',
'count': 1
}]
}]
Rendering works!! :)
But there's no way for me to get a working click event. Ultimately, the click listener needs to give me access to the value selected + the 'field' value. (for example, 'planets', 'jupiter').
This should be easy but I'm unable to get it working. At first I tried nested for loops and creating the components on the fly, but could not add a working click handler (perhaps b/c I'm doing the work within a store load handler function?). I also tried a dataview within the panel (passing in just the array), but the itemSelector isn't triggering. I've tried 'div.facet', 'div.facet_item', (and a few others etc) based on the code, but no luck - it may have been b/c I didn't know how to select them in the this.control() of my controller:
'panel[itemId=pnlFacets] > panel > dataview': {
itemclick: me.facetSelect
}
and the tpl for the dataview attempt:
var tplFacet = new Ext.XTemplate(
'<tpl for=".">',
'<div class="facet">',
//ignore - (this is handled in title of panel) '<label class="facet_field">{facetName}</label>',
'<tpl for="facetEntries">',
'<div class="facet_item">{value} ({count})</div>',
'</tpl>',
'</div>',
'</tpl>'
);

Resources