Firebase $remove() confused about using ref.key() or $id - firebase

I am building a very simple edit/delete function for a list of posts and got the update function working with:
$scope.update = function() {
var fb = new Firebase("https://mydb.firebaseio.com/Posts/" + $scope.postToUpdate.$id);
var article = $firebaseObject(fb);
article.Title = $scope.postToUpdate.Title;
article.Intro = $scope.postToUpdate.Intro;
article.Body = $scope.postToUpdate.Body;
article.$save().then(function(ref) {
console.log($scope.postToUpdate.Title);
}, function(error) {
console.log("Error:", error);
});
}
I assumed that the delete function would be almost identical i.e.
$scope.deletePost = function() {
var fb = new Firebase("https://mydb.firebaseio.com/Posts/" + $scope.postToDelete.$id);
var article = $firebaseObject(fb);
$scope.postToDelete = article;
article.$remove().then(function(ref) {
console.log("removed:" + $scope.postToDelete.Title);
}, function(error) {
console.log("Error:", error);
});
}
button: <button type="button" ng-click="deletePost()">Delete</button>
But nothing happens. I tried the verion with the firebase ref_key instead but this still has not worked
$scope.deletePost = function() {
var fb = new Firebase("https://mydb.firebaseio.com/Posts/" + id);
var id = ref.key();
var article = $firebaseObject(fb);
$scope.postToDelete = article;
article.$remove.then(function(ref) {
console.log("removed:" + $scope.postToDelete.Title);
}, function(error) {
console.log("Error:", error);
});
}
I have been reading through some of the threads and wondering if article should be an array in order to delete the entire object? How do I target the specific item in order to delete it?
FIXED WITH: article.$remove(article).then(function(ref) But I still do not understand when to use ref.key() or $id (firebase/angularfire?)

Related

Fetch LinkedIn Data using JS givs error "message": "Unknown authentication scheme"

I have followed this exemple https://www.c-sharpcorner.com/blogs/fetch-linkedin-data-using-javascript to fetch data like updates/post from a company specific .
I am getting the following error.
{
"errorCode": 0,
"message": "Unknown authentication scheme",
"requestId": "MXRLWYPBNU",
"status": 401,
"timestamp": 1539160527230
}
The company have added my profile as a company admin so I should have the authentication to get the data.
What am I doing wrong ?
Alright here is my code:`
<script type="text/javascript" src="https://platform.linkedin.com/in.js">
api_key: 8616po0krrhh2k
scope: r_basicprofile r_emailaddress
onLoad: onLinkedInLoad,
</script>
$(document).ajaxSend(function (event, jqxhr, settings) {
if (settings.url == "https://www.linkedin.com/uas/oauth/authenticate") {
settings.url = "https://www.linkedin.com/uas/oauth/authorize"
}});
function onLinkedInLoad() {
IN.Event.on(IN, "auth", onLinkedInAuth());}
function onSuccess(data) {
console.log(data); }
function onError(error) {
console.log(error);
}
function onLinkedInAuth() {
var cpnyID = 86104; //the Company ID for which we want updates
IN.API.Raw("/companies/" + cpnyID + "/updates?event-type=status-
update&start=0&count=10&format=json").result(displayCompanyUpdates);
console.log("After auth");
}
function displayCompanyUpdates(result) {
var div = document.getElementById("displayUpdates");
var el = "<ul>";
var resValues = result.values[0];
for (var i in resValues) {
var share = resValues[i].updateContent.companyStatusUpdate.share;
var isContent = share.content;
var isTitled = isContent,
isLinked = isContent,
isDescription = isContent,
isThumbnail = isContent,
isComment = isContent;
if (isTitled) {
var title = isContent.title;
} else {
var title = "News headline";
}
var comment = share.comment;
if (isLinked) {
var link = isContent.shortenedUrl;
} else {
var link = "#";
}
if (isDescription) {
var description = isContent.description;
} else {
var description = "No description";
}
if (share) {
var content = "< a target = '_blank' href = " + link + " > " + comment + "
</a><br>";
el += "<li><div>" + content + "</div></li>";
}
console.log(share);
}
el += "</ul>";
document.getElementById("displayUpdates").innerHTML = el;
}
<div id="displayUpdates"></div>`
well one obvious problem i see with your code, is that you added the wrong scopes for the call you want to make.
for company API calls you need the following scope : rw_company_admin

Firebase infinite loop insert my item on child_added/set

I got an infinite loop inserting an item to my Firebase, so when I click on my post form, it inserts my item until I kill the process. Can you help me how to solve it?
PS : I'm using VueJS
var usersRef = new Firebase('https://xxxxxxxxxxxxxxxxxx.firebaseio.com/userslist/');
var vm = new Vue({
el: '#list1',
data: function () {
return{
// Initialisation du tableau de users
users: [],
sortKey: 'id',
reverse: 1,
nextKey: null
};
},
ready: function () {
// this works
//this.sortKey = 'name';
},
methods: {
updateUsers: function () {
},
removeUser: function (item) {
usersRef.child(item.id).remove();
},
addItem: function (e) {
e.preventDefault();
// get form data as Json
var jsonData = ConvertFormToJSON('form_add');
//console.log(jsonData);//test ok
//get the last item id and save it to next key
usersRef.limitToLast(1).on('child_added', function (snapshot) {
var lastKey = parseInt(snapshot.key());
this.nextKey = lastKey + 1;
console.log('nextKey ' + nextKey);//test ok
//
// save data to firebase
usersRef.child(this.nextKey).set(jsonData, function (snap) {
//console.log('add success');//test
//Notification par Jquery
var itemAdded = snap.val();
$.notify(itemAdded.firstname + " " + itemAdded.name + " à été ajouté", "success", {position: "top right"});
this.pendingKey = 0;
});
});
},
// Tri des colonnes
sortBy: function (_sortKey) {
this.reverse = (this.reverse == -1) ? 1 : -1;
this.sortKey = _sortKey;
console.log("SortKey " + this.sortKey);
}
}
});
usersRef.on('child_added', function (snapshot) {
var item = snapshot.val();
item.id = snapshot.key();
console.log('id ' + item.id);
vm.users.push(item);
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
thanks for your help
OK I've found a solution :
//get the last item id and save it to next key
var _nextKey = this.nextKey;
usersRef.limitToLast(1).on('child_added', function (snapshot) {
var lastKey = parseInt(snapshot.key());
_nextKey = lastKey + 1;
});
this.nextKey = _nextKey;
console.log('nextKey ' + this.nextKey);//test ok
// save data to firebase
usersRef.child(this.nextKey).set(jsonData, function (snap) {
//console.log('add success');//test
//Notification par Jquery
var itemAdded = snap.val();
$.notify(itemAdded.firstname + " " + itemAdded.name + " à été ajouté", "success", {position: "top right"});
});
May it help someone!

template rendered is not working properly in meteor JS

template rendered is not working
when user successfully login in to system i redirect to profile page that time data is not get but if i visit another page and come back to profile page that time it is working fine. also when i reload page that time also it is not working
here is code
Template.profile.rendered = function(){
var user_email = {};
user_email.mail = Session.get('email');
var imgName = Session.get('image');
Meteor.call("imgSend",imgName,function(error, result){
$('.user_profile_image').attr("src",result)
});
Meteor.call("getLinkMeta",user_email,function(error, result){
var link_all_info = [];
var walldata = [];
var total = result.length;
var processed = 0;
var t = result.forEach(function (entry){
var link_info = {};
link_info.link_id = entry._id;
Meteor.call("getCommentList",link_info, function (error, res){
if(error){
console.log("e");
}else{
entry.comments = res;
}
processed++
if(processed == total){
//walldata=result;
}
});
});
Template.profile.walldata = function(){
return result;
};
//return result;
});
}
Router.route('profile', {
path: '/profile',
data: function() {
/* Meteor.subscribe("Users");
Meteor.subscribe("Link");
Meteor.subscribe("Linkfav");
Meteor.subscribe("LinkLike");
Meteor.subscribe("LinkComment"); */
$("body").removeClass('home');
this.render('profile');
setTimeout(function(){
$('#username').html(Session.get('first_name'));
$('#profile_username').html(Session.get('first_name'));
$('#setting_name').val(Session.get('first_name'));
$('#setting_username').val(Session.get('first_name'));
$('#setting_email').val(Session.get('email'));
$('#user_id').val(Session.get('id'));
$('.setting_day').val(Session.get('day'));
$('.setting_month').val(Session.get('month'));
$('.setting_year').val(Session.get('year'));
if(Session.get('image')!= ''){
$('.user_profile_image').attr("src",Session.get('image'));
}
if(Session.get('gender') == 0){
$('#user_gender').html('Male');
}else{
$('#user_gender').html('Female');
}
$('#day').html(Session.get('day'));
$('#month').html(Session.get('month'));
$('#year').html(Session.get('year'));
},100);
},onBeforeAction:function(){
if(Session.get('email')){
this.next();
}else {
//this.next();
this.redirect('/');
}
}
});
When you refresh/reload the page Session values are get undefined. You can get the current user email using meteor.user(). You just have to replace you session.get('email') like this.
var user_email = {};
user_email.mail = Meteor.user().emails[0].address;
I hope that is what you are looking for.

Meteor. Problems with subscribe/publish

i have a problem.
I'm trying to build highcharts graphic.
How it works:
I'm going to my route ('ship.details'), and here i have not problems.
My problem:
subsription to (ships_snapshots_all) not working.
My publish.js:
Meteor.publish("ships_snapshots", function(user, options) {
if(!this.userId) return null;
if(this.userId) {
console.log('subsribed by ' + user);
return ships_snapshots.find({userId: user}, options);
}
});
Meteor.publish("ships_snapshots_all", function() {
return ships_snapshots.find({});
})
My subscribe.js (in lib folder):
Meteor.subscribe('ships_snapshots');
Meteor.subscribe('ships_snapshots_all');
Problem 100% in my subsription, because if i'm installing autopublish all working good. And problem in my router i think.
router.js:
Router.route('/ships/details', {
name: 'ship.details',
loadingTemplate: 'loading',
onBeforeAction: function() {
var shipId = Session.get('currentShipId');
if(!shipId) {
Router.go('user.ships');
} else {
this.next();
}
},
waitOn: function() {
if (Meteor.isClient) {
var getCompare = Meteor.user().profile.wows.compareWith;
console.log(getCompare);
var user2 = Meteor.users.findOne({"profile.wows.nickname": getCompare});
var user2Id = user2._id;
if (getCompare) {
var user2 = Meteor.users.findOne({"profile.wows.nickname": getCompare});
if (user2) {
var user2Id = user2._id;
}
}
if (getCompare) {
var handle = Meteor.subscribe('ships_snapshots', Meteor.user()._id) && Meteor.subscribe('ships_snapshots', user2Id) && Meteor.subscribe('userSearchInfo', getCompare);
Session.set('compareWith', user2);
console.log('user2 _____');
console.log(user2);
return handle
} else {
var handle = Meteor.subscribe('ships_snapshots', Meteor.user()._id) && Meteor.subscribe('ships_snapshots', user2Id);
return handle
}
}, data: function() {
if (handle.ready()) {
var shipname = this.params.shipName;
var obj = {};
var query = ships.findOne();
var shipId = Session.get('currentShipId');
var result;
_.each(Meteor.user().profile.wows.ships, function(row) {
if (row.ship_id === shipId) {
result = row;
}
});
return result;
}
}
});
I think my problem in subscripion for ship_snapshots. Something going wrong here, but i can't to resolve this problem.
What exactly do you mean by "not working"? From your code I would assume that you're always seeing all the ship snapshots.
You shouldn't have the subscribes in /lib if you have them in your router. If you have Meteor.subscribe('ships_snapshots_all'); in /lib then you should always be seeing all the ship snapshots (assuming you're not stopping that subscription anywhere).
Also your subscription to all should be:
Meteor.publish("ships_snapshots", function(user, options) {
if(this.userId) {
console.log('subsribed by ' + user);
return ships_snapshots.find({userId: user}, options);
} else this.ready();
});
You don't want to return null when there is no user, you can just mark the subscription as ready without finding any records. This is not the cause of your problem but just good practice.
Meteor.publish("ships_snapshots", function(user, options) {
if(!this.userId) return null;
if(this.userId) {
console.log('subsribed by ' + user);
return ships_snapshots.find({userId: user._id}, options);
}
});
In your publish script, is user really an id or is it a user object? I changed it to user._id. Please check that.

MeteorJS: Collection.find fires multiple times instead of once

I have an app that when you select an industry from a drop down list a collection is updated where the attribute equals the selected industry.
JavaScript:
Template.selector.events({
'click div.select-block ul.dropdown-menu li': function(e) {
var selectedIndex = $(e.currentTarget).attr("rel");
var val = $('select#industryPicker option:eq(' + selectedIndex + ')').attr('value');
var oldVal = Session.get('currentIndustryOnet');
if(val != oldVal) {
Session.set('jobsLoaded', false);
Session.set('currentIndustryOnet', val);
Meteor.call('countByOnet', val, function(error, results){
if(results > 0) {
Session.set('jobsLoaded', true);
} else {
getJobsByIndustry(val);
}
});
}
}
});
var getJobsByIndustry = function(onet) {
if(typeof(onet) === "undefined")
alert("Must include an Onet code");
var params = "onet=" + onet + "&cn=100&rs=1&re=500";
return getJobs(params, onet);
}
var getJobs = function(params, onet) {
Meteor.call('retrieveJobs', params, function(error, results){
$('job', results.content).each(function(){
var jvid = $(this).find('jvid').text();
var job = Jobs.findOne({jvid: jvid});
if(!job) {
options = {}
options.title = $(this).find('title').text();
options.company = $(this).find('company').text();
options.address = $(this).find('location').text();
options.jvid = jvid;
options.onet = onet;
options.url = $(this).find('url').text();
options.dateacquired = $(this).find('dateacquired').text();
var id = createJob(options);
console.log("Job Created: " + id);
}
});
Session.set('jobsLoaded', true);
});
}
Template.list.events({
'click div.select-block ul.dropdown-menu li': function(e){
var selectedIndex = $(e.currentTarget).attr("rel");
var val = $('select#perPage option:eq(' + selectedIndex + ')').attr('value');
var oldVal = Session.get('perPage');
if(val != oldVal) {
Session.set('perPage', val);
Pagination.perPage(val);
}
}
});
Template.list.jobs = function() {
var jobs;
if(Session.get('currentIndustryOnet')) {
jobs = Jobs.find({onet: Session.get('currentIndustryOnet')}).fetch();
var addresses = _.chain(jobs)
.countBy('address')
.pairs()
.sortBy(function(j) {return -j[1];})
.map(function(j) {return j[0];})
.first(100)
.value();
gmaps.clearMap();
$.each(_.uniq(addresses), function(k, v){
var addr = v.split(', ');
Meteor.call('getCity', addr[0].toUpperCase(), addr[1], function(error, city){
if(city) {
var opts = {};
opts.lng = city.loc[1];
opts.lat = city.loc[0];
opts.population = city.pop;
gmaps.addMarker(opts);
}
});
})
return Pagination.collection(jobs);
} else {
jobs = Jobs.find()
Session.set('jobCount', jobs.count());
return Pagination.collection(jobs.fetch());
}
}
In Template.list.jobs if you console.log(addresses), it is called 4 different times. The browser console looks like this:
(2) 100
(2) 100
Any reason why this would fire multiple times?
As #musically_ut said it might be because of your session data.
Basically you must make the difference between reactive datasources and non reactive datasources.
Non reactive are standard javascript, nothing fancy.
The reactive ones however are monitored by Meteor and when one is updated (insert, update, delete, you name it), Meteor is going to execute again all parts which uses this datasource. Default reactive datasources are: collections and sessions. You can also create yours.
So when you update your session attribute, it is going to execute again all helper's methods which are using this datasource.
About the rendering, pages were rendered again in Meteor < 0.8, now with Blaze it is not the case anymore.
Here is a quick example for a better understanding:
The template first
<head>
<title>test</title>
</head>
<body>
{{> hello}}
</body>
<template name="hello">
<h1>{{getSession}}</h1>
<h1>{{getNonReactiveSession}}</h1>
<h1>{{getCollection}}</h1>
<input type="button" name="session" value="Session" />
<input type="button" name="collection" value="Collection" />
</template>
And the client code
if (Meteor.isClient) {
CollectionWhatever = new Meteor.Collection;
Template.hello.events({
'click input[name="session"]': function () {
Session.set('date', new Date());
},
'click input[name="collection"]': function () {
CollectionWhatever.insert({});
}
});
Template.hello.getSession = function () {
console.log('getSession');
return Session.get('date');
};
Template.hello.getNonReactiveSession = function () {
console.log('getNonReactiveSession');
var sessionVal = null;
new Deps.nonreactive(function () {
sessionVal = Session.get('date');
});
return sessionVal;
};
Template.hello.getCollection = function () {
console.log('getCollection');
return CollectionWhatever.find().count();
};
Template.hello.rendered = function () {
console.log('rendered');
}
}
If you click on a button it is going to update a datasource and the helper method which is using this datasource will be executed again.
Except for the non reactive session, with Deps.nonreactive you can make Meteor ignore the updates.
Do not hesitate to add logs to your app!
You can read:
Reactivity
Dependencies

Resources