First of all, I want to apologize for my poor English.
The last week I started to explore AngularJS in the Ionic framework with Firebase as backend. But I’ve stumbled upon a problem that I can’t solve for the past 3 days.
The purpose is when I chose a storage place and confirm it, an inventory will be created with a date and a link to the storage place to know to which storage place the inventory belongs. After that a list of products will be shown. When you chose a product, a new screen appears where you can add the amount of that product.
My problem is, I can create an inventory after confirmation, but it seems like I can’t insert the product with the amount inside the just created inventory.
Before insertion:
- Inventories
- Date: 1449767729166
- storage: "My Storage place 1"
I want my database looks like this after the insert:
- Inventories
- Date: 1449767729166
- storage: "My Storage place 1"
- Products:
- Name: Heineken
- Boxes: 12
- Bottles: 6
Here is my code:
addProducts.html
<div class="list">
<label class="item item-input item-floating-label">
<span class="input-label"><p>Aantal volle bakken/boxes</p></span>
<input type="text" placeholder="Aantal volle bakken/boxes" ng-model="products.boxes">
</label>
<br>
<label class="item item-input item-floating-label">
<span class="input-label"><p>Aantal (losse) flessen</p></span>
<input type="text" placeholder="Aantal (losse) flessen" ng-model="products.flessen">
</label>
<br>
<button class="button button-block button-dark" align="left" ng-click="AddProducts(products)">
Toevoegen
</button>
</div>
controllers.js:
.controller('AddProductCtrl', function($scope, $state, Inventory, Product) {
$scope.products = Inventory;
$scope.products = Product;
var now = Firebase.ServerValue.TIMESTAMP;
$scope.AddProducts = function(products) {
var query = Product.orderByChild(products.storage).equalTo('now');
query.once('child_added', function(snapshot) {
snapshot.ref().child('Products').push({
'Boxes' : fullBox,
'Bottles': losFles
});
});
}})
services.js
.factory('Product', ['$firebaseArray', function($firebaseArray) {
var addProductRef = new Firebase('https://testdb-1.firebaseio.co/Inventories/');
return $firebaseArray(addProductRef); }])
My Firebase structure:
Firebase structure
This is the error I got:
Error: Product.orderByChild is not a function
I already tried serveral things but with no success.
I'm really new to this. So, please point out what I did wrong.
Thanks in advance!
Your Product factory returns a $firebaseArray, which does not have an orderByChild() method.
I can't really figure out your use-case, but one way to solve the error message:
.factory('Product', ['$firebaseArray', function($firebaseArray) {
var addProductRef = new Firebase('https://testdb-1.firebaseio.co/Inventories/');
return addProductRef;
}])
So instead of returning a $firebaseArray this returns a Firebase reference, which has the orderByChild method you're looking to use.
And then:
$scope.AddProducts = function(products) {
var query = Product.orderByChild(products.storage).equalTo('now');
query.once('child_added', function(snapshot) {
snapshot.ref().child('Products').push({
'Boxes' : fullBox,
'Bottles': losFles
});
});
I believe the confusion comes from mixing up the Firebase SDK with the AngularFire API.
You properly create Products factory using a $firebaseArray(), but then you try to use it like a regular Firebase reference.
A $firebaseArray() takes in a Firebase references and wraps all of the child events (child_added, child_changed, etc...) and create a synchronized array.
You can try using a factory to get the products:
.constant('FirebaseUrl', '<my-firebase-app>')
.service('rootRef', ['FirebaseUrl', Firebase])
.factory('productsByDate', function(rootRef, $q) {
return function productsByDate(storage) {
var deferred = $q.defer();
var productRef = rootRef.child('products'); // or however you get there
var localNow = new Date().getTime();
var query = Product.orderByChild(storage).equalTo(localNow);
query.once('value', function(snapshot) {
deferred.resolve(snapshot);
});
return deferred.promise;
};
});
Try this in your controller:
.controller('AddProductCtrl', function($scope, $state, Inventory, Product, productsByDate) {
$scope.products = Inventory;
$scope.products = Product;
var now = Firebase.ServerValue.TIMESTAMP;
$scope.AddProducts = function(products) {
// get your products by date
productsByDate(products.storage).then(function(snapshot) {
snapshot.ref().child('Products').push({
'Boxes' : fullBox,
'Bottles': losFles
});
});
});
});
Related
So i have a table with a list of teams, what i want to do is when i click on a team name it displays a new view with team details. There is 2 controllers, 1 to get league table and fixtures and then 1 for the team details. So far i have from the controller in the league table looped through the Json object array and gotten a list of links which contains the ID i need to pass in to the team details controller so i can specify which team it should display. Because the teams dont have the ID in the object i had to do it this way.
So the problem is that i can console.log all ID's but it only passes through the last ID logged. Which genereates the same team what ever team i click on. I want to get the specific ID for the team i click on and pass that to the team details controller id:.
I'm in the learning stages so excuse my poor code :).
If you see any improvements in my code writing please do let me know.
I get my data from:
http://api.football-data.org/
using the AngularJs factory library from:
https://github.com/JohnnyTheTank/angular-footballdata-api-factory
The View
<tbody>
<tr ng-repeat="team in teams.standing | filter:searchText | orderBy:orderByField:reverseSort">
// Where i want to somehow click on a team name and load that teams details
<td><strong>{{ team.teamName }}</strong></td>
</tr>
</tbody>
Controller1
.controller('AppCtrl', ['$scope', 'footballdataFactory', function($scope, footballdataFactory) {
$scope.date = new Date();
var apiKey = '***********************';
$scope.$back = function() {
window.history.back();
};
$scope.leagueId = function(id) {
$scope.id = id;
footballdataFactory.getLeagueTableBySeason({
id: $scope.id,
apiKey: apiKey, // Register for a free api key: http://api.football-data.org/register
}).success(function (data) {
$scope.teams = data;
$scope.leagueCaption = data.leagueCaption;
console.log("Get League", $scope.teams);
console.log('Loop through league and get team ids ----------------------------');
$scope.getTeamId = function(teamId) {
var dataLength = $scope.teams.standing.length;
for(var tUrl = 0; tUrl < dataLength; tUrl++) {
$scope.teamUrl = $scope.teams.standing[tUrl]._links.team.href.substr($scope.teams.standing[tUrl]._links.team.href.lastIndexOf('/') +1);
console.log('teamId: ' + $scope.teamUrl);
}
}
});
};
$scope.league = function(id) {
$scope.id = id;
footballdataFactory.getFixtures({
league: $scope.id,
apiKey: apiKey,
}).success(function(data){
$scope.games = data;
console.log("getFixtures", $scope.games);
});
};
}])
Controller2
// Team details controller
.controller('TeamCtrl', ['$scope', 'footballdataFactory', function($scope, footballdataFactory) {
var apiKey = '*************************';
footballdataFactory.getTeam({
id: $scope.teamUrl, ***Inserting the last 2 or 3 digits i get from the url***
apiKey: apiKey,
}).success(function(data){
$scope.teams = data;
$scope.name = data.name;
$scope.crestUrl = data.crestUrl;
$scope.squadMarketValue = data.squadMarketValue;
console.log("getTeam", $scope.teams);
});
footballdataFactory.getPlayersByTeam({
id: $scope.teamUrl,
apiKey: apiKey,
}).success(function(player){
$scope.players = player.players;
console.log("getPlayersByTeam", player);
});
}])
You can solve this problem easly with apiNG and the football-data plugin, that based on the same angular lib you even use. on the plugin page is a link to a working plnkr sample
At first sorry for my english ..and for someone maybe stupid question but Im new at programming in Angular,Node, Express and mongoDB together...
My question is If it is possible to make something like realtime search in DB . I am writing the query for search on the client side (angular + HTML) the matched result from mongoDB will show somewhere on the page (with number of similar word). I need to do it in the Angular and MongoDB using Node and Express for routing
Example situation: In the browser I will write some word etc. cook and in my database are saved data like (cook, cooker, cooking) ...The result that I would like to show is whole row of table with Cook and number of similar words with cook in the word so 3 is the answer ...
I would like to know what I have to study,and use for it
HTML would look like this I think ? ..:
<form method="post" ng-submit="find()" name="findForm">
<div class="form-group">
<input class="form-control input-lg" type="text" name="word"
ng-model="word" placeholder="search from Mongo" >
</div>
<button type="submit" class="btn btn-lg btn-block btn-success">search
</button>
But I dont know whats next ...some controller with http post method or what ..? ..
angular.module('MyApp')
.controller('SearchCtrl', ['$scope', '$http', function($scope, $http) {
$http.post('/api/search', $scope.word)
$scope.search= function() {
({
-----??
});
};
}]);
Is it right ? ...should it works ..? ..Last function should be in the server.js file where I have to implement function for find word in my DB..isn it ?
app.post('/api/search', function(req, res) {
Word.find(........)
// here I dont know how ..
});
I will be very thankfull if somebody get me some advice how to pass through that ...thanks ..
I m sorry if I dont explain my problem too clear ..if you have some more question what I am lookin for ..ask please ..
THANKS..
Yes it is possible to real time search. you can use RegExp for partial search. can try this process.
you used ng-submit="find()" in your dom so you need a find function in controller and from this function call the api:
$scope.find = function() {
$http.post('/api/search', $scope.word).then(function(response) {
$scope.words = response.data;
//your code
});
};
and in server side
app.post('/api/search', function(req, res) {
var query = {};
//generetae query for partial search
query.word = new RegExp(req.body.word, 'i');// assume word is field name for query.word
Word.find(query, function(error, words){
if(error) {
return res.status(400).send({msg:"error occurred"});
}
return res.status(200).send(words);
});
});
N.B: better to use get verb for search if no problem to show query data
model ? ..did you mean module ? ..
angular.module('SymText')
.controller('FreeWrtCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.find = function () {
$http.post('/api/find',$scope.word)
.then(function (response) {
$scope.words = response.data;
})
}
}]);
And the server-js :
app.post('/api/find', function (req, res) {
var query={};
query.word=new RegExp(req.body.word, 'i');
//console.log(req.body.word);
User.find(query, function (err, words) {
if (err) return res.status(400).send({msg:" error during search DB"});
console.log(words);
return res.status(200).send(words);
}
)
});
and my model for now in Mongo look like ..:
var userSchema = new mongoose.Schema({
username: {type: String, unique: true, required: true},
password: {type: String, required: true},
fullname: {type: String, required: true},
role: Number
});
..its not the main mongo DB but in that DB i ve got some data...for testing its good I think.. and thats wouldnt be the problem for me isnt it? ..
I have an app where I need to store artists and their details in database.Now I want to retrieve all the artists and render some of their details in front end.How to do that.
Secondly, if I get the artist rating in some input field by using ng-model, then how to store that value in a particular artist to update details.
The database structure is:
{
"artists": {
"Atif":{
"name":"atif",
"rating":8
},
"Himesh":{
"name":"himesh",
"rating":5
}
}
}
and this is angular.js
(function()
{
var app = angular.module("myapp", ["firebase"]);
app.controller("maincontroller", function($scope, $firebaseObject,$firebaseArray)
{
var ref = new Firebase("https://gigstart.firebaseio.com/");
var artists=ref.child("artists");
// download the data into a local object
$scope.data = $firebaseObject(ref);
// putting a console.log here won't work, see below
ref.on("value", function(snapshot)
{
console.log(snapshot.val());
}, function (errorObject)
{
console.log("The read failed: " + errorObject.code);
});
var artistsRef=new Firebase("https://gigstart.firebaseio.com//artists");
}); //end of controller
Now I want to render the name and rating of each artist in front end.Can I do something like
<div ng-repeat="artist in artists">
{{artist.name}}
{{artist.rating}}
</div>
You have a list of artists, which you want to ng-repeat over in your Angular view. You can accomplish that by:
app.controller("maincontroller", function($scope, $firebaseArray)
{
var ref = new Firebase("https://gigstart.firebaseio.com/");
var artists = ref.child("artists");
$scope.artists = new $firebaseArray(artists);
}
Please take a moment to go through the AngularFire quickstart before starting on your own project. This is covered in step 5.
What I am doing is putting the filter on table (contains records). When I type into search box (used http get method), table data get updated as per search box. But when I type very fast, then I see in console 500 Internal Server error.
The main problem is before comming previous response I am firing the next request.
There is no problem in result. Just console shows every http request. And in case of fast typing in search box it gets red.
What is the solution for it?
you could trottle your search input :
var app = angular.module('app', []);
app.controller('TableController', function($scope, $http, $timeout) {
$http.get('yourTableData.json').then(function(result){
$scope.rows = result.data;
});
$scope.filterText = '';
var temp = '',
filterTextTimeout;
$scope.$watch('searchText', function (val) {
if (filterTextTimeout){
$timeout.cancel(filterTextTimeout);
}
temp = val;
filterTextTimeout = $timeout(function() {
$scope.filterText = temp;
$http.get($scope.filterText).then(function(result){
$scope.rows = result;
}
}, 250);
})
});
<input id="searchInput" type="search" placeholder="search field" ng-model="searchText" />
<div class="record" ng-repeat="row in rows | filter:filterText">
<span>{{row.content}}</span>
</div>
I am using Angularfire and I'd like to save data by multiple checkbox.
HTML
<form role="form" ng-submit="addTask(task)">
<label class="checkbox-inline" ng-repeat="(key, value) in students">
<input type="checkbox" id="{{key}}" value="{{key}}" ng-model="task.student[value.name]">{{value.name}}
</label>
<button type="submit">Submit</button>
</form>
JS
var ref = new Firebase(FURL);
var fbTasks = $firebaseArray(ref.child('tasks'));
$scope.addTask = function(task) {
fbTasks.$add(task);
}
This was the result
student
--Alison Kay: true
--Jessica Cook:false
--John Smith: true
--Kevin Hunt: true
My question is there any way to save them like this?
student
--(key)
--name:Alison Kay
--checked: true
--(key)
--name:Jessica Cook
--checked: false
--(key)
--name:John Smith
--checked: true
--(key)
--name:Kevin Hunt
--checked: true
I threw together a rough example PLNKR to demonstrate one way to do this by extending the AngularFire services.
Note that the documentation states:
These techniques should only be attempted by advanced Angular users who know their way around the code.
Solution
You can create a factory that extends $firebaseObject, and adds a method .addTask() which uses .push() to generate a new key for a new task.
Factories:
app.factory("TaskList",function($rootScope, $q, fbUrl, TaskListFactory){
return function(studentKey){
var ref = new Firebase(fbUrl+'/tasks/'+studentKey);
return new TaskListFactory(ref);
}
});
app.factory("TaskListFactory",function($firebaseObject, $q, fbUrl, $rootScope){
return $firebaseObject.$extend({
addTask: function(name, checked){
// use push to generate a new key, set `name` and `checked`
this.$ref().push({name: name, checked: checked}, function(error){
if(!error){
console.error(error);
} else {
console.log("Pushed new task.");
}
});
}
});
});
Controller:
Note: I used mock objects. I couldn't decode your data structure, and took a best guess approach.
app.controller('HomeController',function($scope,fbUrl, $firebaseObject, TaskList) {
// create mock student and task
$scope.students = {tester: {name: 'tester'} };
$scope.task = {tester: {name: 'test this'}};
var taskList = new TaskList('student123');
// get tasks list for debug:
var tasksRef = new Firebase(fbUrl+'/tasks');
$scope.tasks = $firebaseObject(tasksRef);
$scope.addTask = function(task) {
console.debug(task);
taskList.addTask('Tester McGee', task.student['tester']);
}
});
Result (<firebaseUrl>/tasks):
{
"$id": "tasks",
"$priority": null,
"student123": {
"-JoMxWoX0tQrGtdP6Qvm": {
"checked": true,
"name": "Tester McGee"
}
}
}
Again, the focus of this is on the factories, and not on the data structure. The form data in my example doesn't make sense.
Hope that helps.