angular ui router passing just the data from $http get - javascript

resolve: {
document: function ($stateParams, specialGet, $http) {
var id = $stateParams.id
return specialGet(id)
},
},
.factory('specialGet', function (Pusher, $q, $http) {
return function (id) {
return
$http.get('/api/document/'+id)
}
})
When I inject document into my controller I get an object with these properties
config: Object
data: Object
headers: function (name) {
status: 200
statusText: "OK"
How do I pass just the data into document instead of the return being this object and having to get the data afterwards?

Continue on the http promise using the then method, and return the desired data there.
resolve: {
document: function ($stateParams, $http) {
var nid = $stateParams.id
return $http.get('/api/document/'+id).then(function(response) { return response.data; });
},
},

Related

Angular scope items not applies after item change

I have items service,items list controller, and item details controller:
.state('dashboard.items', {
url: '/items',
templateUrl: '/js/components/dashboard/items/items.html',
controller:'itemsListCtrl'
})
.state('dashboard.items.details', {
url: '/:id',
templateUrl: '/js/components/dashboard/items/itemDetails.html',
controller: 'itemDetailsCtrl',
resolve:{
items: function (ItemService) {
if(!ItemService.items)
ItemService.getAll().then(function (res) {
ItemService.items = res.data;
});
}
}
})
app.factory('ItemService', function ($http) {
var itemsFactory = {};
itemsFactory.getAll = function () {
return $http.get('/items');
}
itemsFactory.update = function () {
itemsFactory.items[0].name = "sadasd";
}
return itemsFactory;
})
app.controller('itemsListCtrl', function($scope, $state, ItemService){
if(!ItemService.items) {
ItemService.getAll().then(function (res) {
ItemService.items = res.data;
$scope.items = ItemService.items;
});
}else{
$scope.items = ItemService.items;
}
})
app.controller('itemDetailsCtrl', function ($scope, items, ItemService) {
$scope.item = ItemService.items[0];
$scope.item.name = "abc" ;
$scope.update = function(){
ItemService.update();
}
})
I have ng-click button which invokes the edit() function.
I made it simple for the example, when doing the update, and edit the item name, the item that presents in the list doesnt change.
I dont know what I miss here. The list sits in the service, and both controllers use it for their purposes.
What am I doing wrong? What is best practice for this scenario?
Update 1
Found something weird. When I edit the item in the controller initialization, it changes the original value globally. When it happens via the edit() method, it doesn't. What happnes?
Thanks.
$http.get returns a promise that it will return your data, so in .then you can do your stuff and it will execute when done(async)
$http.get('/items').then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
return response.data;//this is your data
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});

Showing 'details' of specific object- pass JSON value from one page to another to query API

I want to pass a value from one element, to another html page.
Very simply- I want to click an object (within an ng-repeat), and be directly to a page with more detail about that object only.
Take a value (product_id) from the $http getUrl (a value not a directive in my html- can javascript still find it?). Pass this value so it can be accessed if "more info" is requested.
Using a value from take the current product_id, and use that number to fill a getURL to pull a json object for the following "detail" page.
Using ui-sref it opens a new page (not a new URL address, just a different HTML document)
In this new page it should have the product details
This is my my attempt:
.factory('cardsApi', ['$http', function ($http) {
var apiUrl = 'http://stashdapp-t51va1o0.cloudapp.net/api/item/';
function productId(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
var getApiData = function () {
return $http.get(apiUrl + productId(1, 50000))
};
var postRecordLikes = function (product_id) {
return $http.post('http://test.com/analytic/' + product_id);
}
return {
getApiData: getApiData,
postRecordLikes: postRecordLikes
};
}])
.controller('CardsCtrl', ['$scope', 'TDCardDelegate', 'cardsApi', '$http',
function ($scope, TDCardDelegate, cardsApi, $http) {
console.log('CARDS CTRL');
$scope.cards = [];
$scope.onSwipeRight = function (product_id) {
console.log(product_id)
}
$scope.onSwipeLeft = function (product_id) {
console.log(product_id)
}
// <====== Rewrite with accounts preferences
for (var i = 0; i < 7; i++) {
cardsApi.getApiData()
.then(function (result) {
//console.log(result.data) //Shows log of API incoming
$scope.cards.unshift(result.data);
$scope.product_id = result.data.product_id;
})
.catch(function (err) {
$log.error(err);
});
}
// Rewrite with accounts preferences =====>
$scope.$watchCollection('cards', function (newVal, oldVal) {
if (newVal < oldVal) {
cardsApi.getApiData()
.then(function (result) {
// console.log(JSON.stringify(result.data)); Shows log of API results
$scope.cards.unshift(result.data);
// console.log($scope.cards);
})
//.catch(function (err) {
// console.log(err);
//});
}
});
$scope.cardSwiped = function (card) {
console.log(card);
postRecordLikes(card);
};
//$scope.cards = Array.prototype.slice.call(cardTypes, 0);
//Removes card from top of stack
$scope.cardDestroyed = function (index) {
$scope.cards.splice(index, 1);
};
$scope.addCard = function () {
var newCard = $scope.cards[$scope.cards.length];
//newCard.id = Math.random();
$scope.cards.push(angular.extend({}, newCard));
};
var postRecordLikes = function (product_id) {
cardsApi.postRecordLikes(product_id)
.then(function successCallback(product_id) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
};
}
])
.controller('ProductsCtrl', ['$scope', 'TDCardDelegate', 'productApi', '$http',
function ($scope, TDCardDelegate, cardsApi, $http) {
console.log('PRODUCTS CTRL');
}
])
.factory('productApi', ['$http',
function($http) {
var apiUrl = 'http://stashdapp-t51va1o0.cloudapp.net/api/item/' + product_id;
var getApiData = function() {
return $http.get(apiUrl)
};
return {
getApiData: getApiData
};
}]
)
My routing.js (trying to configure it to direct to any URL containing integers/numbers). This always redirects back to login...:
c
.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/login");
$stateProvider
.state('login', {
url: '/login',
views: {
'menuContent': {
templateUrl: 'app/core/login/login.html'
}
},
controller: function ($ionicHistory, $scope) {
console.log('Clearing history!');
$ionicHistory.nextViewOptions({
historyRoot: true,
disableBack: true
});
}
})
.state('product', {
url: '/product',
when:('/product/?:product_id'),
views: {
'menuContent': {
templateUrl: 'app/components/product/product.html'
}
}
})
a query string adds data to the end of a url, after a question mark. you then navigate to that url:
var myvar=234;
location="http://www.example.com/?"+myvar;
and in the second page get the variable by accessing the query string and stripping away the question mark:
var newvar=location.search.replace("?", ""); // 234
you would then use the 234 to make the specific ajax call, get the JSON, etc, etc

angular injecting resolve into controller logging undefined

I have the following resolve:
.state('posts', {
url: '/posts/{id}',
templateUrl: 'posts.html',
controller: 'postsController as postsCtrl',
resolve: {
post: getSinglePostWrapper
}
})
and helper function
getSinglePostWrapper.$inject = ['postsService', '$stateParams'];
function getSinglePostWrapper(postsService, $stateParams) {
return postsService.getSinglePost($stateParams.id);
}
and my controller looks like this:
angular.module('flapperNews')
.controller('postsController', postsController);
postsController.$inject = ['postsService', 'post'];
function postsController(postsService, post) {
var vm = this;
vm.post = post;
console.log(post); //undefined here
}
I'm getting an undefined "post" when I try to inject the post from the resolve. I tried logging the post in the getSinglePostWrapper function, and it logs the correct object. I seem to be losing some binding or something from the resolve to the controller.
posts service
angular.module('flapperNews')
.factory('postsService', postsService);
postsService.$inject = ['httpService'];
function postsService(httpService) {
return {
getSinglePost: getSinglePost
}
function getSinglePost(postId) {
httpService.baseGet('/posts/' + postId)
.then(function(data) {
return data;
}, function(data) {});
}
}
httpservice
angular.module('httpService', [])
.factory('httpService', httpService);
httpService.$inject = ['$http', '$q'];
function httpService($http, $q) {
return {
baseGet: baseGet
}
function baseGet(url) {
return $http.get(url).then(
function (result) {
return result.data;
},
function (result) {
return $q.reject(result);
}
);
}
}
and I've injected httpservice into the first place I declare the flapperNews module.
FYI- everything is working. Other http requests are fine. This one is fine too. It just doesn't inject the post into the controller.
Promise chain breaks here.
function getSinglePost(postId) {
httpService.baseGet('/posts/' + postId)
.then(function(data) {
return data;
}, function(data) {});
}
You don't return the promise, hence post will be resolved to undefined before httpService.baseGet request has been finished.
try this:
.state('posts', {
url: '/posts/{id}',
templateUrl: 'posts.html',
controller: 'postsController as postsCtrl',
resolve: {
post: function('postsService', '$stateParams') {
return postsService.getSinglePost($stateParams.id);
}
})
angular.module('flapperNews')
.controller('postsController', function($scope, post){
$scope.post = post;
console.log($scope.post); //undefined here
});

How to use promises correctly with callback function

I've this service, it returns a list of students asynchronously using callback:
studentModule.factory('StudentService', function (DB_URL) {
return {
getAllStudents: function (callback) {
var Datastore = require('nedb'),
path = require('path');
db = {};
db.students = new Datastore({
filename: DB_URL + '/students.db',
autoload: true
});
db.students.find({}, function (err, stds) {
callback(stds);
});
}; //end return
My old way to use it in controller:
StudentService.getAllStudents(function(sts) {
$scope.students = sts;
$scope.$apply();//notify angular about the change
});
This works for me, but now i want to use some best practices. I need to resolve the result in the route before coming to the controller, here what i did:
.state('payment', {
url: '/payment',
templateUrl: 'frontend/components/payment/views/payment.html',
controller: 'PaymentController',
resolve: {
students: function (StudentService, $q) {
var defer = $q.defer();
defer.promise.then(function () {
StudentService.getAllStudents(function (sts) {
alert(JSON.stringify(sts));
return sts;
});
})
defer.resolve();
}
}
})
The alert is returning data from the route successfully but not from the controller - i get an undefined in the controller:
paymentModule.controller('PaymentController', function($scope,students) {
alert(JSON.stringify(students));
Any help will be appreciated!
You should always return a promise to resolve functions, and, when creating a promise of your own, you should resolve it with the data you need to pass along with it.
.state('payment', {
url: '/payment',
templateUrl: 'frontend/components/payment/views/payment.html',
controller: 'PaymentController',
resolve: {
students: function (StudentService, $q) {
var defer = $q.defer();
//defer.promise.then(function () {
StudentService.getAllStudents(function (sts) {
//alert(JSON.stringify(sts));
//return sts;
defer.resolve(sts);
});
//})
//defer.resolve();
return defer.promise
}
}
})

Angular custom $update function "is not a function"

I'm trying to make an update function to replace some data on an user.
I've created the factory:
factory('Details', ['$resource', function ($resource) {
return $resource('/api/client/:id', null, {
'update': { method: 'PUT'}
});
}]);
and the controller:
.controller('ClientDetails', function ($scope, Details, $routeParams) {
$scope.client = Details.query({ id: $routeParams.id });
$scope.editClient = function () {
$scope.client.$update();
}
});
and when entering function editClient() it throws and error:
$scope.client.$update is not a function
What have I done wrong? Thanks
By default, the query method is defined to return an array of instances: 'query': {method:'GET', isArray:true}, see documentation for ng-resource. And the array does not have the $update method. From your code, you need to use the get to fetch the instance, like this:
$scope.client = Details.get({ id: $routeParams.id });
$scope.editClient = function () {
$scope.client.$update();
}

Categories

Resources