Auto-adding new item - Angular UI query - angularjs

I'm adding a 'new stories' feature to a website for authors to contribute work to. The function below allows stories to be created and added to the author's profile but doesn't auto-add them to a list (ie I have to refresh the browser for this to work. Does anyone know if there is a way to do this (I've tried changing state back to 'authorprofile' but that didn't work).
self.addStory = function() {
var authorId = tokenService.getAuthor()._id;
console.log(authorId);
var data = {
story: self.currentStory,
authorId: authorId
}
Story.save(data, function(story) {
console.log("saving: " + story);
Story.put(data, function(story){
console.log("story added");
})
// auto-add new stories here
$state.go('authorprofile');
})
}

Assuming the list of stories is stored in a 'stories' variable on the scope:
// auto-add new stories here
$scope.stories.push(data);

Add new story into the array using in the success function using push method.
Story.save(data, function(story) {
//Add stories to the array
$scope.stories.push(story);
Story.put(data, function(story){
console.log("story added");
})
// auto-add new stories here
$state.go('authorprofile');
})

Related

Cannot link to a webpart on SPO page with certain parameters

I have created a hyperlink which opens up a modal that shows a specific item from a SharePoint Online list.
Here's what I've got so far (with help from AmosWu!):
private _filterListOnEmail = () => { //this runs on componentdidmount
var urlParams = new URLSearchParams(window.location.search);
var urlParamstoString = urlParams.toString();
var justUrl = window.location.href;
var trimHref = justUrl.split('&')[0];
var trimHref2 = trimHref.substring(trimHref.indexOf("=") + 1);
var txtUrlParams = urlParams.toString();
var trimtxtUrlParams = txtUrlParams.substring(3);
this.setState({
urlParams: trimHref2
}, () => {
if(urlParamstoString){
this.setState({
showWelcomeModal: true,
ByEmail: 'Yes',
});
}
The URL I have constructed:
<a href={`https://mytenant.sharepoint.com/sites/MySite?ID=${this.props.id}`}>Here</a>
This works if the URL is https://mytenant.sharepoint.com/sites/MySite?ID=1 and it shows my modal and it gets the correct ID and shows the correct list item. But if it's ID=2 or any other number, the page shows No item exists at
https://mytenant.sharepoint.com/sites/MySite/SitePages/Home.aspx?ID=2
I don't understand why it's putting the extra SitePages/Home.aspx on the end....I guess this is causing the No item exists error.
The webpart is on the home page of the SP site.
It works with any ID number in workbench but not when deployed.
Really need help with this.
My test result:
I show the editform in the modal, it works well.
The code is the code I shared with you in Q&A. If you need the complete project code, please let me know and I will share it on Github.

backbone fetch on a nested route

I have a Sitesand a Positionscollection. Each time the user selects a new site, the id is sent to the refreshPositions method which is in charge of doing the fetch call.
The route to get the positions look like this '.../sites/1/positions'
view.js
refreshPositions: function(siteId) {
this._positions.fetch({
success: this.onPositionsFetchSuccess.bind(this),
error: this.onPositionsFetchError.bind(this)
});
},
So refreshPositions is called whenever I need to update the positionson the page and the siteId parameter has the id, I just don't know to tell fetch to route to something like .../sites/n/positions where n would be the siteId .
Sorry if I missed relevant informations for my question, I'm pretty new to backbone.
I see, so you are calling fetch from your Positions Collection. The out-of-the-box functionality there is to fetch the whole collection (every Position object) if you have a RESTfull api set up. If you want more specific behaviour from your collection, you can probably write it into the Collection object definition.
var PositionCollection = Backbone.Collection.extend({
initialize: function(models, options) {
this.siteId = (options && options.siteId) || 0;
},
url: function() {
if (!this.siteId) {
return '/positions'; // or whatever
}
return '/sites/' + this.siteId + '/positions';
},
// etc...
});
Then, assuming that _positions refers to an instance of PositionCollection you can do:
refreshPositions: function(siteId) {
this._positions.siteId = siteId; // or wrap in a setter if you prefer
this._positions.fetch({
success: this.onPositionsFetchSuccess.bind(this),
error: this.onPositionsFetchError.bind(this)
});
},

Filter data by user with angularfire

I'm using angular-ui-fullcalendar to show and edit events. Users can log in and have unique uid when logged in. I want to use this to distinguish events made by current user from other events. I want to give current user events another backgroundColor.
What is the best way to do this??
I tried several things. My data looks like this:
```
database
bookings
-KWnAYjnYEAeErpvGg0-
end: "2016-11-16T12:00:00"
start: "2016-11-16T10:00:00"
stick: true
title: "Brugernavn Her"
uid: "1f17fc37-2a28-4c24-8526-3882f59849e9"
```
I tried to filter all data with current user uid like this
var ref = firebase.database().ref().child("bookings");
var query = ref.orderByChild("uid").equalTo(currentAuth.uid);
var bookings = $firebaseArray(query);
$scope.eventSources = [bookings];
This doesn't return anything. If I omit the filter in line 2 it returns all bookings as expected. But even if the filter worked it would not solve my problem, because I want to fetch both current user events and all other events. Firebase does not have a "not equal to" filter option...
I tried to loop through each record and compare uids and setting backgroundColor if condition was met:
var ref = firebase.database().ref().child("bookings");
var bookings = $firebaseArray(ref);
bookings.$ref().on("value", function(snapshot) {
var list = snapshot.val();
for (var obj in list) {
if ( !list.hasOwnProperty(obj) ) continue;
var b = list[obj];
if (b.uid === currentAuth.uid) {
b.className = "myBooking";
b.backgroundColor = "red";
}
}
});
$scope.eventSources = [bookings];
But this causes asynchronous problems so the 'bookings' array assigned to $scope.eventSources wasn't modified. I tried to move the $scope.eventSources = [bookings] inside the async code block but FullCalendar apparently can't handle that and renders nothing.
I also tried this but no luck either:
bookings.$loaded()
.then(function(data) {
$scope.eventSources = [data];
})
.catch(function(error) {
console.log("Error:", error);
});
What is the best solution to my problem?
If you're looking to modify the data that is loaded/synchronized from Firebase, you should extend the $firebaseArray service. Doing this through $loaded() is wrong, since that will only trigger for initial data.
See the AngularFire documentation on Extending $firebaseArray and Kato's answer on Joining data between paths based on id using AngularFire for examples.

how to make a select query to firebase

I am using angularfire.
I have my node in firebase /texts/ and it loos like that:
{ title: 'title', text: 'long text' }
In my service i want to get just the title because i want to show a list of the titles and i don't want to load the texts at this moment because usually are a very long texts.
My service looks like that:
var ref= new Firebase( FBURL+'/texts' );
var sync = $firebase(ref);
var text = sync.$asArray();
this.getTitle = function(){
var deferred = $q.defer();
var titles = [];
text.$loaded().then(function(data){
lodash.forEach(data, function(item){
titles.push({title: item.title});
});
deferred.resolve(titles);
})
.catch(function(err){
$state.go('login');
deferred.reject(err);
});
return deferred.promise;
};
I have noticed that inside the variable text there are all the objects so i get everything included the text. What i want to to is just a select name from texts :)
Thanks
When you access Firebase through most of its APIs, it will always retrieve complete nodes. So you can not tell it to retrieve only a subset of the properties.
That means that if you really only want the titles, you'll have to model your data differently. Right now you have something like this:
posts
-Jas73489342
title: "how to make a select query using firebase"
text: "...."
-Jasa8324023
title: "bicycling the grand canyon"
text: "..."
Those -J things are the keys that Firebase generates when you call push.
In order to be able to retrieve just the titles, you'll need to make sure that there is a node that contains just the titles. So let's split up our posts into two separate nodes: titles and texts.
titles
-Jas73489342: "how to make a select query using firebase"
-Jasa8324023: "bicycling the grand canyon"
texts
-Jas73489342: "...."
-Jasa8324023: "..."
To add a new post to the above structure, you'd do something like:
var ref = new Firebase(FBURL),
titles = ref.child('titles'),
texts = ref.child('texts'),
item = { title: 'Petroglyphs in Albuquerqe', text: '...' };
var newItemRef = texts.push(item.text);
var key = newItemRef.key();
var newTitleRef = titles.child(key).set(item.title);
So we first add the text of the new post to the texts node and then use the same key to add the title under the titles node.
You could also leave the posts node as is, but add a titles node with just the titles. Either way you'll have a node that represents precisely what you want: a list of titles.

Get one Post back in backbone via fetch on a collection

I have the following collection:
AisisWriter.Collections.Posts = Backbone.Collection.extend({
model: AisisWriter.Models.Post,
// Build the url based on blog id.
url: function() {
url = '/api/v1/blogs/' + AisisWriter.blog_id + '/posts/'
return url;
}
});
this allows me to do:
var options = { reset: true };
this.writer_posts.fetch(options).then(this.postsRecieved, this.serverError);
this will return me all posts, current six.
I have tired to do:
var options = { reset: true };
this.writer_posts.fetch({id: id}).then(this.postsRecieved, this.serverError);
// id is the id passed into the route, in this case it's #=> {id: 6}
But this still returns me all six posts, I have seen this answer, but I don't think I should have to go through, or extend the model in the middle of code just to append an ID, that and I use the model for the Post, Put and Delete actions while I use the collection for fetching data.
So how do I return one post?
In general, to get some Model from Collection, you should fetch Collection and then get needed model by id, for example:
this.writer_posts.fetch();
And after Collection will be fetched you get method
this.writer_posts.get(id);
Or you can try to fetch a specific Model by passing required id in the fetch method:
this.writer_posts.fetch({
data: {
id: id
}
});
Or something like that.

Resources