I have recently started working with backbone.js and i am finally started to get my head around after many tutorials.
One thing i am stuck on is how to use the routing to allow a list to pull different rest request.
Say i have the following in my collection
var NewsCollection = Backbone.Collection.extend({
model : News,
url: 'http://api.example.com/index.php/news/all/format/json',
});
From my understanding correct me if i am wrong backbone stores all the data pulled from the above feed into my model that extends this collection, this will all work i will pull in the feed and then display it in the view
This is where i get confused within my routing i have the following.
var NewsRouter = Backbone.Router.extend({
routes: {
"": "defaultRoute",
"news/:country_code":"updatedRoute"
},
defaultRoute: function () {
console.log("defaultRoute");
var movies = new NewsCollection()
new NewsView({ collection: movies });
movies.fetch();
//setInterval(function(){movies.fetch({success: function(){}});}, 60000);
},
updatedRoute:function (country_code) {
//confused
this.movie = this.movies.get(country_code);
}
})
I need to run the updatedRoute function when that will display a list of news based on cat of country code see below.
http://api.example.com/index.php/news/country/gb/format/json
How do i update the whole feed when a list item is click so the browser url would be.
http://localhost:8888/backbonetut/#news/gb
my list item is.
<li><a href='#news/gb'>GB</a></li>
I can get that in the updateRoute function with
this.movie = this.movies.get(country_code);
Can someone please help
You can either override the fetch function on your collection or temporarily change the url of the collection in your router action.
Related
aye folks!
I'm currently learning to do stuff with vue.js. unfortunately i'm stuck atm. what i want to do is sending a request to my sample API which responds with a simple json formatted object.
I want to have this object as data in my component – but it doesn't seem to do that for whatever reason.
Ofc i tried to find a solution on stackoverflow but maybe i'm just blind or this is just like the code other people wrote. i even found this example on the official vue website but they're doing the same thing as i do .. i guess?
btw. When i run the fetchData() function in a separate file it does work and i can access the data i got from my API. no changes in the code .. just no vue around it. i'm really confused right now because i don't know what the mistake is.
code:
var $persons = [];
and inside my component:
data: {
persons: $persons,
currentPerson: '',
modal: false
},
created: function() {
this.fetchData()
},
methods: {
fetchData: function () {
var ajax = new XMLHttpRequest()
ajax.open('GET', 'http://api.unseen.ninja/data/index.php')
ajax.onload = function() {
$persons = JSON.parse(ajax.responseText)
console.log($persons[0].fname)
}
ajax.send()
}
},
[...]
link to the complete code
First, make sure that the onload callback is actually firing. If the GET request causes an error, onload won't fire. (In your case, the error is CORS-related, see this post suggested by #Pradeepb).
Second, you need to reference the persons data property directly, not the $persons array that you initialized persons with.
It would look like this (inside your fetchData method):
var self = this;
ajax.onload = function() {
self.persons = JSON.parse(ajax.responseText)
console.log($persons[0].fname)
}
Working on a node script to automatically call Google's pagespeed api upon giving the sites listed in a json file.
{
"1" : "https://bitbucket.org",
"2" : "https://www.catswhocode.com/blog/"
}
The aim is to add the results for the api call to firebase json database along with a top-level url node to store the firebase key for the sitestats entered. Here is example firebase data structure I need.
sites
-KrehhWxld7XlKCuFSHRY
stats { ... }
url: "https://bitbucket.org"
-KrehhXAWlYdjAOA9sd95
stats { ... }
url: "https://stackoverflow.com"
urls :
393957be871e209a76e0dc5df1f526ec : -KrehhWxld7XlKCuFSHRY
7f4c919540be6ec81cd37d9e61da6c37 : -KrehhXAWlYdjAOA9sd95
Within a promise I am adding a reference for the nodes in firebase json database.
Promise.all(allRes).then( function( values ) {
var ref = db.ref();
var sitesRef = ref.child("sites");
var urlsRef = ref.child("urls");
var psiresults = {};
SitesArray.map(function (sites, index) {
psiresults[sites] = values[index]
desktopStats = values[index].desktopStats;
mobileStats = values[index].mobileStats;
sitesRef.push({
url: sites,
stats: metricsResponse
});
sitesRef.once('child_added', function(snapshot) {
console.log(snapshot.key) //returns the last key only
});
});
When using once('child_added', ... it adds to the url top level node only for the very last item. However, if on('child_added', ... multiple copies of the same data and other childs are added. Not sure how to add the exact child key to the urls top level node when a child is added to sites node each time.
If you want to process all URLs once, use once('value' with snapshot.forEach():
sitesRef.once('value', function(snapshot) {
snapshot.forEach(function(child) {
console.log(child.key);
});
});
Finally, I had to do it using..
sitesRef.on('value', function(snapshot) {
...
});
This returns all the children and then I am able to filter the result based on my SitesArray values. I don't really find this an appropriate solution, however, I was able to make it work.
I have put the question at the bottom as the only way I could explain my problem was with an example so with out the example it might not make sense but feel free to skip down to the bottom and just read the question.
I will use this example to try give some idea of what I do understand and where my understanding falls down.
I want to build a page where I can browse through a collection of items which I would set up like this:
angular.module('App')
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('browse', {
url: '/browse',
templateUrl: 'app/browse/browse.html',
controller: 'BrowseCtrl',
title: 'Browse',
mainClass: 'browse'
});
}]);
Each item is pulled through and place on this page using ng-repeat and then calling an api:
$scope.items = [];
$http.get('/api/items').success(function(items) {
$scope.items = items;
socket.syncUpdates('Item', $scope.items);
$scope.totalItems = $scope.items.length;
$scope.$watch('currentPage + itemsPerPage', function() {
var begin = (($scope.currentPage - 1) * $scope.itemsPerPage),
end = begin + $scope.itemsPerPage;
$scope.filteredItems = $scope.items.slice(begin, end);
});
});
This then accesses the api and repeats out the items. So far so good. Heres an example of the API setup. Worth mentioning I am using the Angular-fullstack generator which plugs in to Mongo DB using Express & Sockets.io
Item.find({}).remove(function() {
Item.create({
"image_url" : "../../../assets/images/test.jpg",
"title" : "Test Item",
"created_on" : new Date(2014, 9, 23, 3, 24, 56, 2),
"creator" : {
"profile_img" : "../../../assets/images/stephanie-walters.jpg",
"username" : "StephW",
"url" : "/stephanie-walters",
"first_name" : "Stephanie",
"last_name" : "Walters",
}
}
Ok now this is where things start to get unclear for me.
I now need to create the item pages, so that when I click on an item I get access to the content of that item. Short of creating every single page for every entry I would very much like to be able to create a page template that ui-router is able to attach content to when the correct url structure is met.
Thats probably not clear so let me try be a bit clearer. Lets say if we follow that JSON above I want to go to 'Stephanie Walters' profile I am going to need three things.Firstly a profile template, secondly I need the content for the profile in an api call and lastly a dynamic url that can take that api content and put it in to the page template.
Perhaps something similar to:
.state('profile.username', {
url: '/:username',
templateUrl: '/partials/profile.username.html',
controller: 'profileUsernameCtrl'
})
But I don't exactly understand how to get the take a variable like username from the item JSON(above) and then use that to build a URL /:username that connects to a template page profile.username.html and further still fill that page with the users content that is stored in another API call.
To "build a url" so to speak, you need to use the ui-sref directive.
Given a state like so:
.state('profile.username', {
url: '/:username',
templateUrl: '/partials/profile.username.html',
controller: 'profileUsernameCtrl'
})
to create a link to this state use:
<a ui-sref="profile.username({username: user.name})">{{ user.name }}</a>
where user is an attribute on the scope where that link is displayed.
For more complex URLs you just add additional parameters like so:
.state('browse.item', {
url: '/:username/:itemId'
})
To get the parameters you use the $stateParams service in your controller like so:
.controller('MyController', function($scope, $stateParams) {
$scope.username = $stateParams.username;
$scope.itemId = $stateParams.itemId;
})
I hope someone can help me with this, It's a strange question maybe as I didn't find an answer online.
I call the database and retrieve a list (in json) of items.
Then in angularjs,I render this list by extracting relevant pieces of data(name,age,etc) and show it properly in a table as a list of rows.
I have then an edit button that takes me to another page where I want to put a dropdown list.
What I want to know if is possible to add to that dropdown list the rendered list I previously created in my previous page.
is it possible to save the previously rendered list in a variable and then use that variable in the dropdown?
thank you
You could store the list within a controller and make this data availablte to this dropdown, I think.
Instead of trying to query for the list, add the list to the template, get the list from the template and render somewhere else, I'd suggest query for the list, save the list in a service , and then when you want to use that list again, get it from the service. Something like:
service:
var services = angular.module('services');
services.factory('getListService',['$http',function($http){
var getListOfStuff = function(){
//call to database
return //your json
};
var extractNameAgeEtc = function(){
var myListOfStuff = //get list of stuff from $http or database
var myListOfNameAgeEtc = //make a list of tuples or {name,age,etc} objects
return myListOfNameAgeEtc;
};
return {
extractNameAgeEtc : extractNameAgeEtc
};
}]);
controllers:
angular.module('controllers',['services']);
var controllersModule = angular.module('controllers');
controllersModule.controller('tableRenderController',['getListService','$scope',function(getListService,$scope){
//use this with your table rendering template, probably with ng-repeat
$scope.MyTableValue = getListService.extractNameAgeEtc();
}]);
controllersModule.controller('dropdownRenderController',['getListService','$scope',function(getListService,$scope){
//use this with your dropdown rendering template, probably with ng-repeat
$scope.MyDropDownValue = getListService.extractNameAgeEtc();
}]);
Is this possible.. here's what I have atm, but my data object is just returning a load of jargon, what am I doing wrong? Am I doing anything.. right, for that matter?
I basically want to print out a list of a users videos (thumbnail and title, and make each one a clickable link to the video itself)
Thanks!
$(document).ready(function(){
$player.init();
})
var $player = (function(){
var player = {};
player.init = function(){
//init Youtube knockout
player.initYoutubeKnockout();
}
player.knockoutModel = {
videoData : ko.observableArray([]),
}
player.initYoutubeKnockout = function()
{
//load the Youtube json feed
$.ajax({
url: 'http://gdata.youtube.com/feeds/api/users/USERNAME/uploads?v=2&alt=json',
type: 'GET',
dataType: 'jsonp',
data: {
count: 5
},
success: function(data, textStatus, xhr) {
player.doYoutubeKnockout(data.item);
}
});
}
player.doYoutubeKnockout = function( data )
{
player.knockoutModel.videoData(data);
ko.applyBindings(player.knockoutModel, $('#youtube-feed')[0]);
console.log($(this));
}
return player;
})();
Frankly you weren't doing much at all.
The JSON data you get back from YouTube is not from data.item, it's in a completely different structure.
I'm assuming you wish to get 5 uploads from the user. The parameter name would be max-results, not count.
Probably the only thing you did fine was set up the url but that's about it.
You need to examine how the JSON returned looks like. Check the API reference for the structure of an atom feed. This is in XML but the corresponding JSON responses will have pretty much the same format with some minor differences. Examine the object by writing it to the console to verify you're getting the right properties.
Once you understand that, you need to use the correct query to get what you're expecting. Check out their API reference on their query parameters.
To help simplify your knockout code, I would strongly recommend you take the response you get back and map it to an object with simplified property names. For instance, to get the thumbnails for an entry, you would have to access the media$group.media$thumbnail array. It would be easier if you can just access it through thumbnail.
Also, if your elements you are binding to need to bind multiple values, it would help to map the values in such a way that your bindings are made easier. For instance, when using the attr binding, you'd set up a property for each of the attributes you want to add. Instead you could just group all the properties in an object and bind to that.
I wrote up a fiddle applying all that I said above to do as you had asked for. This should help give you an idea of what you can do and how to do it.
Demo