I'm building a forum, and I'm in the step of views. I have this (simplified) code:
//Setting Views
//Adding Them..
$scope.views = $firebaseObject(refService.ref().child("Topics"))
refService.ref().child("Topics").once("value", function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key();
var childData = childSnapshot.val();
if(childData.DateCreated == $stateParams.DATE && childData.Email == $stateParams.EMAIL){
refService.ref().child("Topics").child(childData.pushKey).child("Views").child(currentAuth.uid).set({
Views : true
})
}
})
})
//Viewing them
$scope.viewableView = $firebaseObject(refService.ref().child("Topics"))
As you can see adding the views was pretty easy job. And I did it correctly. The problem is with displaying the number of views, and I have to do it using AngularFire's $firebaseObject, or $firebaseArray... Here is the structure in database:
{
"Topics" : {
"-KG9rDNLZksJDiLfAXwH" : {
"Avatar" : "http://cs624223.vk.me/v624223037/2b1bb/GRTKddkmXiw.jpg",
"DateCreated" : 1461544873669,
"Email" : "abogale2#gmail.com",
"Title" : "Check",
"UID" : "3caf2136-7a2d-4ae4-a4a9-119f2b08133c",
"Username" : "BruhBrhu",
"Value" : "Check",
"Views" : {
"3caf2136-7a2d-4ae4-a4a9-119f2b08133c" : {
"Views" : true
}
},
"pushKey" : "-KG9rDNLZksJDiLfAXwH"
}
},
"UserAuthInfo" : {
"3caf2136-7a2d-4ae4-a4a9-119f2b08133c" : {
"BronzeBadge" : 0,
"Description" : "Just a wierd 15 year old coder...",
"Email" : "abogale2#gmail.com",
"GoldBadge" : 0,
"Image" : "http://cs624223.vk.me/v624223037/2b1bb/GRTKddkmXiw.jpg",
"Moderator" : false,
"Password" : "KfUcQ1yedOi1gEnGP6i1KQ==",
"PlatinumBadge" : 0,
"SilverBadge" : 0,
"UID" : "3caf2136-7a2d-4ae4-a4a9-119f2b08133c",
"Username" : "BruhBrhu"
}
}
}
As you can see I used push(), to get the topic.. My Concern now is how to view the topics! Please Help! I can't think of a "algorithm" to do it!
Mind you, all of the topics have unique ID's. I have to get the specific ID The user is in.
This worked for me:
refService.ref().child("Topics").once("value", function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key();
var childData = childSnapshot.val();
if(childData.DateCreated == $stateParams.DATE && childData.Email == $stateParams.EMAIL){
refService.ref().child("Topics").child(childData.pushKey).child("Views").on("value", function(snapshot){
console.log(snapshot.numChildren())
$scope.countViews = snapshot.numChildren();
})
}
})
})
I dont know how but somehow $scope.countViews, became three way binded to my HTML, so it actually shows!
You're nesting keys inside an object, which the Firebase documentation explicitly recommends against.
But it can work once you realize that you can also add methods to the scope:
var app = angular.module('app', ['firebase']);
app.constant('FB_URL', 'https://yours.firebaseio.com/');
app.controller('MainCtrl', function(FB_URL, $scope, $firebaseArray, $firebaseObject) {
var ref = new Firebase(FB_URL);
$scope.topics = $firebaseArray(ref.child('Topics'));
$scope.getCount = function(obj) {
return Object.keys(obj).length;
};
});
And the view:
<body ng-controller='MainCtrl'>
<ol><li ng-repeat='topic in topics'>{{topic.Title}} - {{topic.Username}} - {{getCount(topic.Views)}}</li></ol>
</body>
Working jsbin: http://jsbin.com/dapoga/edit?html,js,output
Related
I have 2 collection tables that only share emails as the unique ids of these 2 tables. The first one is Meteor.users() and SchoolStudents. I want to update the SchoolStudents collection based on the user's email. Though I have successfully updated using _id but the update isn't working using email as the Id. What's the better approach?
In this, it returned a success feedback but no update is made to the record. Bert.alert('Record updated successfully', 'success', 'growl-top-right');
Client code:
let user = Meteor.user();
let studentemail = user && user.emails && user.emails[0].address;
if (studentemail) {
console.log(studentemail);
Meteor.call('UpdateUser', studentemail, function (error, response) {
if (error) {
Bert.alert(error.reason, 'danger', 'growl-top-right');
return false;
} else {
Bert.alert('Record updated successfully', 'success', 'growl-top-right');
}
})
}
Server method
SchoolStudents.update({useremail: studentemail}, {$set: {'status.active': true, 'status.activedate': new Date()}});
This is a sample document from the SchoolStudents collection:
{
"_id" : "xgxZJFRkXGhHmHupY",
"firstname" : "Kehinde",
"lastname" : "Adeoya",
"middlename" : "Adekusibe",
"username" : "ken10ward",
"password" : "PvyLwY9d",
"useremail" : "kadeoya#appzonegroup.com",
"studentclass" : "ss8",
"dateofbirth" : "9-Mar-00",
"gender" : "f",
"ethinicity" : "black",
"mobile" : "8023472442",
"address" : "7 Abrahamoivc",
"city" : "bolson",
"lg" : "loveland",
"state" : "ekiti",
"country" : "Ukraine",
"registra" : "kadeoya",
"status" : {
"active" : false,
"activedate" : null
},
"userId" : "n5rqFSHbhm7zqADyB",
"createdAt" : ISODate("2017-09-05T18:45:14.877Z"),
"friendlySlugs" : {
"slug" : {
"base" : "kehinde-adeoya",
"index" : 5
}
},
"slug" : "kehinde-adeoya-5"
}
This is the server update code:
UpdateUser: function (studentemail) {
check(studentemail, String);
if (!Meteor.userId()) {
Meteor.Error('Not authorized');
return false;
} else {
SchoolStudents.update({useremail: studentemail}, {status: {active: true, activedate: new Date()}}, { upsert: true });
}
}
As it has been pointed to you, you're using user && user.emails && user.emails[0].address construct wrong way.
I suggest you to use this template to do things like that:
let studentemail;
try {
studentemail = user.emails[0].address.valueOf();
} catch (e) {
studentemail = null;
}
if (studentemail != null) {
...
}
This way you can omit numerous checks, like user != null and user.emails != null and user.emails.length > 0 etc and it will be guaranteed that in your studentemail variable you will get either null or user email address.
Added: User email address could be undefined, that's why you need != null check (non-strict). It will be false if variable is undefined or null.
This is currently how my firebase database looks.
I am trying to perform an update where when I click the like button, the user will appear in liked attribute (the second one above). currently it is just hardcoded but the code is not doing quite what i want it to do.
function liked(name, useruid, user_liked){
var postData = {
name: name,
useruid: useruid,
user_liked: user_liked
};
var newPostKey = firebase.database().ref().child('users').push().key;
var updates = {};
updates['/users/' + name + '/' + '/liked/' + user_liked] = postData;
return firebase.database().ref().update(updates);
}
I call this function with liked(current_user_name, user_array[i].useruid, 'Hannah')
I would like then the liked: "liked attribute to read liked: "liked", "Hannah"
However instead it does the following below:
It has added in information I do not want and instead of adding to the array it has transformed it. it must be a tiny change but i cant quite see it
exported json before update:
{
"users" : {
"rich" : {
"gender" : "male",
"liked" : "liked",
"name" : "rich",
"not_liked" : "liked",
"username" : "rich#rich.com",
"useruid" : "5xO85K2EBOS6Itj7lKoGafm19i02"
}
}
}
exported json after update:
{
"users" : {
"rich" : {
"gender" : "male",
"liked" : {
"Hannah" : {
"name" : "rich",
"user_liked" : "Hannah",
"useruid" : "5xO85K2EBOS6Itj7lKoGafm19i02"
}
},
"name" : "rich",
"not_liked" : "liked",
"username" : "rich#rich.com",
"useruid" : "5xO85K2EBOS6Itj7lKoGafm19i02"
}
}
}
. Sample of collection Flights :
{
"Orig" : "AGP",
"Dest" : "CMN",
"Description_Flight" : "One-Stop-Narrow Type",
"Description_Flight_2" : "WESTERN EUROPE/WESTERN EUROPE",
"Mkt_Al" : "0B"
}
. Sample of collection Coeff :
{
"Regions" : "WESTERN EUROPE/WESTERN EUROPE",
"Non-Stop-Narrow Type" : 2.4109,
"Non-Stop-Supersonic" : 2.71828,
"One-Stop-Narrow Type" : 2.22554,
"One-Stop-Turbo" : 0.92312,
"One-Stop-Wide Type" : 11.24586,
"One-Stop Online-Turbo" : 0.07577
}
What I want ?
I Have my starting collection, Flights and for each document I want to put a score, a score which based on the Description_Flight_2 and Description_Flight.
Example :
For example, in my sample I have :
"Description_Flight" : "One-Stop-Narrow Type",
"Description_Flight_2" : "WESTERN EUROPE/WESTERN EUROPE",
So, I should go to the Coeff collection, and find the region :
"WESTERN EUROPE/WESTERN EUROPE"
and then take the appropriate value, here I should take this value in this line :
"One-Stop-Narrow Type" : 2.22554,
I have tried this :
mongoose.connect('mongodb://localhost/mydb');
var cSchema = new Schema({},{ strict: false, collection: 'flights' }),
dflights = mongoose.model("flights", cSchema);
var rSchema = new Schema({},{ strict: false, collection: 'coeff' }),
coeff = mongoose.model("coeff", rSchema);
mongoose.set('debug', false);
mongoose.connection.on("open", function (err) {
if (err) throw err;
dflights.find({}).lean().exec(function (err, flights) {
if (err) throw err;
flights.forEach(function(flight) {
var Flight_Description = "", score =0 ;
coeff.findOne({Regions : flight.Description_Flight_2}).lean().exec(function (err, coef) {
And here the important lines :
Flight_Description = flight.Description_Flight;
score = (coef != null ) ? coef.Flight_Description : "Missed data";
Here the last lines
if ( score != 0)
dflights.collection.update({_id:flight._id}, { $set : { score :score } } );
});
});
});
});
Please how can I achieve the above ?
The correct code should be:
score = (coef != null ) ? coef[Flight_Description] : "Missed data";
I have added an array of objects to my user collection in my Meteor app, called contacts. It now looks like this:
{
"_id" : "p6c4cSTb3cHWaJqpG",
"createdAt" : ISODate("2016-05-11T11:30:11.820Z"),
"services" : {
.....
},
"username" : "admin",
"emails" : [
{
"address" : "email#email.com",
"verified" : true
}
],
"points" : 28,
"contacts" : [
{
"when" : ISODate("2016-06-02T12:22:53.747Z"),
"who" : "4YBufbE9PByJBkasy"
},
{
"when" : ISODate("2016-06-02T12:00:41.833Z"),
"who" : "EvF7DbFazmiuG86mD"
},
{
"when" : ISODate("2016-06-02T12:21:41.415Z"),
"who" : "MNFTSzjjzmYWgDvey"
}
]
}
I can display the contacts on my page just fine, but they are in the order that they appear in the collection. I would like to sort them by the date in the when field. Is this possible?
My helper method:
Template.contacts.helpers({
'cont': function(){
var user = Meteor.user();
return user;
}
});
and my Template:
<template name="contacts">
{{#each cont.contacts}}
<h1>{{who}}</h1>
{{/each}}
</template>
Akram Saouri was on the right track, I just needed to dig a little deeper. So I'll post the 100% working solution I came up with off that. The docs are your friend
Client.js:
Template.contacts.helpers({
'cont': function(){
var contacts = Meteor.user().contacts;
var result = contacts.sort(function (a,b) {
if (a.when > b.when){
return -1;
}
if (a.when < b.when){
return 1;
}
return 0;
});
return result;
}
});
Blaze Template:
<template name="contacts">
{{#each cont}}
<h1>{{who}}</h1>
{{/each}}
</template>
You can send the contacts array directly from the helpers and pre-sorted it like this :
Template.contacts.helpers({
'cont': function(){
var user = Meteor.user();
var contacts = user.contacts.sort({'when':'-1'})
return contacts;
}
});
In this way, you blaze 'll look much simpler :
<template name="contacts">
{{#each contacts}}
<h1>{{who}}</h1>
{{/each}}
</template>
I persist some DB table column values as json string and later on send DB table values as a json object into front end.
[
{
"jobId":"efe0ace0-8ed9-45ff-9232-974cbdc89b86",
"jobType":"TestExecutionJob",
"nextRun":"N/A",
"lastRun":"2015-11-26 13:26:10.664",
"createdDate":"2015-11-26 13:26:10.664",
"executor":"sam",
"JobDetails":"{\"environment\":\"AA\",\"EmailRecipients\":[\"sam.sam11#gmail.com\"],\"extraParams\":{\"FileName\":\"myTest.xml\"}}",
"status":"active",
"elapsedTime":"18 minutes ago"
}
]
I have tried with angularJs ng-repeatbut nothing display.Please let me know how can i accessJobDetails values.(environment,EmailRecipients and FileName)
<ul><li ng-repeat="t in row.entity.JobDetails">{{t.environment}}</li></ul>
Js File
'use strict';
var tepTableModule = angular.module('test',
[ 'ngAnimate', 'ngTouch','ui.grid','ngResource' ]).factory('Service',
function($resource) {
return $resource('/api/jobs', {});
});
tepTableModule
.controller(
'tepTableCtrl',
function($scope, Service) {
$scope.TestData = Service.query();
var Plantemplate ='<div><ul><li ng-repeat="t in row.entity.JobDetails">{{t.FileName}}</li></ul></div>';
$scope.tableData = {
data : 'TestData',
groupsCollapsedByDefault : true,
enablePinning : true,
columnDefs : [ {
field : 'jobId',
displayName : 'jobId',
visible : false
}, {
field : 'JobDetails',
displayName : 'Plan Name',
cellTemplate : Plantemplate,
visible : true
},
{
field : 'jobType',
displayName : 'JobType',
visible : true
},
{
field : 'environment',
displayName : 'Environments',
visible : true
},
{
field : 'status',
displayName : 'Status',
visible : true
},
{
field : 'elapsedTime',
displayName : 'LastRun',
visible : true
},
{
field : 'JobDetails.EmailRecipients',
displayName : 'Email Recipients',
visible : true
},
{
field : 'executor',
displayName : 'Executor',
visible : true
}
],
sortInfo: {
fields: ['elapsedTime'],
directions: ['desc']
},
plugins : [ new ngGridAutoRowHeightPlugin() ]
};
$scope.changeGroupBy = function(group) {
$scope.gridOptions.groupBy(group);
}
$scope.clearGroupBy = function() {
$scope.gridOptions.$gridScope.configGroups = [];
$scope.gridOptions.groupBy();
}
});
HTML
<div ng-controller="tepTableCtrl">
<div ui-grid="tableData" class="grid"></div>
</div>
first parse string to object and then use it
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', ['$scope', function($scope) {
$scope.json = [
{
"jobId":"efe0ace0-8ed9-45ff-9232-974cbdc89b86",
"jobType":"TestExecutionJob",
"nextRun":"N/A",
"lastRun":"2015-11-26 13:26:10.664",
"createdDate":"2015-11-26 13:26:10.664",
"executor":"sam",
"JobDetails":"{\"environment\":\"AA\",\"EmailRecipients\":[\"sam.sam11#gmail.com\"],\"extraParams\":{\"FileName\":\"myTest.xml\"}}",
"status":"active",
"elapsedTime":"18 minutes ago"
}
].map(function(value){
value.JobDetailParse = JSON.parse(value.JobDetails);
return value;
})
}]);
</script>
Html :
<div ng-repeat = "t in json">
{{t.JobDetailParse.environment}}
</div>
Why not parse the data, IE turn it from string to object?
newObj = JSON.parse(yourString);
Then use ng-repeat on it.