master detail in ionic using json data - angularjs

I'm using ionic v1 and trying to create list and its own detail, but when I click on the item list the detail view doesn't display the data of the item selected.
Factory
.factory('Eventos', function($http){
var eventos = [];
return {
all : function() {
return $http.get("eventos.json").then(function(response) {
eventos = response;
return eventos;
});
},
get : function(eventoId) {
for(i = 0; i < eventos.length; i++) {
if(eventos[i].id === eventoId){
return eventos[i];
}
}
return null;
}
}});
Controller
.controller('EventosCtrl', function($scope, $stateParams, Eventos) {
Eventos.all().then(function(eventos) {
$scope.eventos = eventos.data;
});
})
.controller('EventoCtrl', function($scope, $stateParams, Eventos) {
$scope.evento = Eventos.get($stateParams.eventoId);
}
But if I use the data static in the code this works, but I don't know whats wrong here.

If you're not running a webserver of any kind and just testing with file://index.html, then you're probably running into same-origin policy issues.
Many browsers don't allow locally hosted files to access other locally hosted files.
Try referencing your data as an object
var obj = {list:null};
$http.get('data.json').success(function(data) {
// you can do some processing here
obj.list = data;
});
return obj;

Related

How to pass data between views using stateParameters (not routes) in AngularJS

I have some views in my applications, and I have hard time to show the data when moving from one view to another.
I have a list of news and when I click on the particular news I want the view for that particular news to be shown. Here is my code:
My app.js :
.state('app.list', {
url: "/list",
views: {
'appScreen': {
templateUrl: "list.html",
controller: 'List.Ctrl'
}
}
})
.state('app.singleview', {
url: "/list/:newsId",
views: {
'appScreen': {
templateUrl: "single.html",
controller: 'SingleCtrl'
}
}
})
My controllers:
ListCtrl.$inject = ['$http', '$scope', 'datacontext'];
function ListCtrl( $http, $scope, datacontext) {
$scope.list = [];
datacontext.getPosts().then(function (posts) {
console.log('posts', posts);
$scope.list= posts;
}, function(reason) {
alert(reason);
});
The following controller is the one which will show me the single news and I have written some code but is not correct. In the URL I get the ID but I can't manage to show the data for that ID.
SingleCtrl.$inject = ['$scope', '$stateParams', 'datacontext'];
function ListNewCtrl($scope, $stateParams, datacontext) {
$scope.New = getNewsById($stateParams.newsId);
function getNewsById(id) {
datacontext.getPosts().then(function(posts) {
var found = null;
for (var i = 0; i < posts.length; i++) {
if (posts[i].id == id) {
found = posts[i];
break;
}
}
return found;
})
}
};
So in this controller what I am trying to do is get the ID and match it with postsId, and then show the data accordingly but it does no seem to work
You're confused with the asynchronism. The code should be
getNewsById($stateParams.newsId);
function getNewsById(id) {
datacontext.getPosts().then(function(posts) {
var found = null;
for (var i = 0; i < posts.length; i++) {
if (posts[i].id == id) {
$scope.New = posts[i];
break;
}
}
});
}
So that, when the success callback is executed, the New scope variable is initialized by the found post.
That said, I have a hard time understanding why you're getting a whole list of posts from the backend instead of using a REST service returning a single post by ID. If you did, it would be reduced to
function getNewsById(id) {
datacontext.getPost(id).then(function(post) {
$scope.New = post;
});
}

sample angularjs code which will connects to sqllite

kindly provide a sample code/link/tutorial which will connect to sqllite database from anugular js.
I am new mobile development
Basically when i am calling retriveProfileInfo function which is present in DataAccess.js
retriveProfileInfo function is executing in different thread i wanted in synchronous way.
Controller.js
mympn.controller('MyProfileController', function($scope, $location, ngDialog ) {
$scope.myProfileData = {};
$scope.myProfileDatalist = [];
function callBack(d) {
return d;
}
$scope.myProfileDatalist = retriveProfileInfo(callBack);
alert(myProfileDatalist);
console
.log("After calling retriveProfileInfo ----------------");
});
DataAccess.js
function retriveProfileInfo(callBack) {
var db = DataBaseInstance.getInstance();
var userProfileData = [];
db.transaction(function(tx) {
tx.executeSql("SELECT * from myprofile", [], function(tx, res) {
for (var i = 0; i < res.rows.length; i++) {
userProfileData[i] = res.rows.item(i);
}
});
}, errorCB, sucessCB);
console.log(userProfileData);
return callBack(userProfileData);
}

AngularJS local storage - initialize app retrieving local-stored data

I'm pretty new to angular and I'm trying to avoid losing items added on a simple cart application when the user refreshes the page.
I'm using angularLocalStorage (https://github.com/agrublev/angularLocalStorage) but don't know how to retrieve it back the content.
My lines:
var myApp = angular.module('ionicApp', ['ionic','angularLocalStorage']);
myApp.factory('prodottiData', function($http) {
return {
getFooOldSchool: function(callback) {
$http.get('http://192.168.1.128/hongkongapp/?json=get_recent_posts&post_type=product&custom_fields=all').success(callback);
}
}
});
myApp.factory('DataService', function() {
var myCart = new shoppingCart("AngularStore");
return {
cart : myCart
};
});
myApp.controller('MyController', function MyController ($scope, storage, $ionicSideMenuDelegate, prodottiData, DataService, $sce) {
$scope.toggleLeft = function() {
$ionicSideMenuDelegate.$getByHandle('mainMenu').toggleLeft();
};
$scope.toggleMySecondMenuLeft = function() {
$ionicSideMenuDelegate.$getByHandle('mySecondMenu').toggleLeft();
};
//adding menu data to the scope object
prodottiData.getFooOldSchool(function(data) {
$scope.menu = data;
});
//adding the cart to the scope object
$scope.cart = DataService.cart;
$scope.to_trusted = function(html_code) {
return $sce.trustAsHtml(html_code);
}
images = $scope.menu;
$scope.showloader = function(){
$scope.shownImage = this.post.thumbnail_images.full.url;
$scope.itemDesc = this.post.content;
$scope.itemPrice = this.post.custom_fields._price[0];
$scope.productName = this.post.title;
$scope.skuProdotto = this.post.id;
}
});
Now, if I check local storage on the console I can see something is really stored, but I miss the way to re-populate the cart at startup.
Any help would be great!
why not just using browser local storage ?
you can add it to your services.js as a new service and just used that.
var storeService = myAppServices.factory('storeService', function() {
var service =
{
setClientData:function(client_details)
{
window.localStorage.setItem( "client_data", JSON.stringify(client_details) );
client_data = client_details;
},
getClientData:function()
{
if (client_data == null)
{
client_data = JSON.parse(window.localStorage.getItem("client_data"));
}
return client_data;
}
}
var client_data = null;
return service;
});
From the documentation, to retrieve, it's storage.get('key')
So, to check after refresh:
if (storage.get('someKey')){
$scope.retrieved_value = storage.get('someKey');
}else{
// whatever
}
You can use localStorage instead windows.localStorage.
if(typeof(Storage)!=="undefined")
{
// Code for localStorage/sessionStorage.
var hello = "Hello World!!";
localStorage.setItem("hello",hello);
// get string
console.log(localStorage.getItem("hello")); // will return 'Hello World!!'
var me = {name:'abel',age:26,gender:'male'};
localStorage.setItem("user", JSON.stringify(me));
//fetch object
console.log(localStorage.getItem("user")); // will return {"name":"myname","age":99,"gender":"myGender"}
var objetos = JSON.parse(localStorage.getItem("user"));
console.log(objetos.name);
}
else
{
// Sorry! No Web Storage support..
}

AngularJS service storing and updating data

I have a simple app that shows a list of people each with a link to an edit controller. The edit controller gets the person by id. Once the edit form has been submitted, the page is redirected back to the person list.
I have a method to update the service data in the callback after the server saves the person. The method I use does in fact work, however, I wasn't sure if there was a better way to achieve this. After much searching I haven't found a concrete answer so I wanted to reach out to the AngularJS community here for help.
Here is a fiddle: http://jsfiddle.net/7bGEG/
var app = angular.module('peopleApp',[]);
app.controller('ListCtrl',function($scope,People) {
People.getList().then(function(response) {
$scope.list = response; // show list of people with a link to new route to edit
});
});
app.controller('EditCtrl',function($scope,$location,$routeParams,People) {
// edit route so get person by id
People.getById($routeParams.id).then(function(response) {
$scope.person = response.person;
});
// submit save person form and send back to person list
$scope.savePerson = function() {
People.savePerson($scope.person).then(function(response) {
$location.path('/');
});
}
});
app.factory('People',function($http,$q) {
var people = [];
var people_q = $q.defer();
$http.get(url).then(function(response) {
people = response.data;
people_q.resolve(people);
});
return {
getList: function() {
return people_q.promise;
},
getById: function(id) {
return $http.get(url).then(function(response) {
return response.data;
});
},
savePerson: function(person) {
return $http.post(url).then(function(response) {
// find person in person array and remove them
for (i=0; i < people.length; i++) {
if (people[i].person_id == person.person_id) {
people.splice(i,1);
break;
}
}
// add new person data
people.push(response.data);
return response.data;
});
}
}
});

AngularJS workflow problems - list -> detail -> list

I'm new to Angular and am trying to implement an infinite scroll. I'm running into two challenges that I'm not sure how to solve. First I want to show a list of apps using the ngInfiniteScroll. This is working nicely. I used their example code to get up and running.
Now I want to click on an app to view the details. I have the view displaying, but I'm not sure how to share the apps list from one controller to the next.
//// AppCatalog constructor function to encapsulate HTTP and pagination logic
applicationCatalog.factory('AppCatalog', function($http) {
var AppCatalog = function() {
this.apps = [];
this.selectedApps = [];
this.busy = false;
this.after = '';
this.page = 1;
this.maxresults = 50;
};
AppCatalog.prototype.nextPage = function() {
if (this.busy) return;
this.busy = true;
var restUrl = "/web-portal/apps/catalog/search?page="+this.page+"&maxresults="+this.maxresults;
$http({method: 'GET', url: restUrl}).success(function(data) {
var apps = data;
for (var i = 0; i < apps.length; i++) {
this.apps.push(apps[i]);
}
this.after = this.apps[this.apps.length - 1].id;
this.page += 1;
this.busy = false;
}.bind(this));
};
return AppCatalog;
});
applicationCatalog.controller('appCatalogController', ['$scope', 'AppCatalog',
function(scope, AppCatalog) {
scope.appcatalog = new AppCatalog();
}
]);
So first off, instantiating a new AppCatalog() into appcatalog doesn't feel right, as it results in starting over every time I go from list to details back to list. This code does work and infinite scroll correctly produces the next batch of apps. Shouldn't the apps list be stored for the lifecycle of my angular page and only refreshed when I refresh the page or navigate away from it. How would I change this code to do this?
My second challenge, but probably related, is that when I want to view details of an app, which I already have downloaded in the apps list I don't know how to access them.
applicationCatalog.controller("appDetailsController", ['$scope', '$routeParams', 'AppCatalog',
function(scope, params, appcatalog) {
scope.appcatalog = appcatalog;
var id = params.id;
scope.id = id;
///TODO - this doesn't work appcatalog is empty
var appcatalog = $scope.appcatalog;
for(var i = 0; i < appcatalog.apps.length; i++) {
var app = appcatalog.apps[i];
if(app.id == params.id) {
$scope.app = app;
return;
}
}
}
]);
In the appDetailsController I want to pull the app from the list based on the id. But I don't know how to access the apps list from the second controller. It should already be in memory.
Finally when I return the list (this relates to my first question) from this details controller it starts over. My paging info, current location in the scroll list, etc are all lost. This workflow must be a common one, but I'm not sure where to go from here.
Thanks in advance for your help.
Jared
Ok. After deciding that my JavaScript needs a little work and I need to be careful about copying and pasting solutions from the web here is my updated solution. This is the fixed solution to my questions above. I don't know if it's perfect and am open to suggestions for improvement.
var applicationCatalog = angular.module('applicationCatalog', ['infinite-scroll', 'ngRoute']);
///necessary hack
applicationCatalog.run(function($http){
window.http = $http;
});
/*
* Small config with template mapping
*/
applicationCatalog.config(function($routeProvider){
$routeProvider
.when("/", {
templateUrl: '../assets/scripts/angular/views/appList.html'
})
.when("/apps/details/:id", {
templateUrl: '../assets/scripts/angular/views/appDetails.html'
})
.otherwise({
redirectTo: "/"
});
});
applicationCatalog.factory('AppCatalog', function($http) {
var apps = [];
var activeApps = [];
var activeAppIds = '';
var busy = false;
var after = '';
var page = 1;
var maxresults = 50;
var nextPage = function () {
if (busy) return;
busy = true;
var restUrl = "/web-portal/apps/catalog/search?page="+page+"&maxresults="+maxresults;
$http({method: 'GET', url: restUrl}).success(function(data) {
var newApps = data;
for (var i = 0; i < newApps.length; i++) {
apps.push(newApps[i]);
}
after = apps[apps.length - 1].id;
page += 1;
busy = false;
}.bind(this));
};
var addNewApp = function (id, appcatalog) {
this.activeApps.push(id);
var ids = "";
for(var i = 0; i < this.activeApps.length; i++) {
if(ids.length > 0) ids += ",";
ids += this.activeApps[i];
}
this.activeAppIds = ids;
}
return {
apps: apps,
activeApps: activeApps,
activeAppIds: activeAppIds,
busy: busy,
page: page,
after: after,
maxresults: maxresults,
nextPage: nextPage,
addNewApp: addNewApp
};
});
applicationCatalog.controller('appCatalogController', ['$scope', 'AppCatalog',
function(scope, appcatalog) {
var catalog = appcatalog;
if(catalog.apps.length == 0) catalog.nextPage();
scope.appcatalog = catalog;
}
]);
applicationCatalog.controller('appCatalogSelectedController', ['$scope', 'AppCatalog',
function(scope, appcatalog) {
var catalog = appcatalog;
scope.appcatalog = catalog;
}
]);
applicationCatalog.controller('appDetailsController', ['$scope', '$routeParams', 'AppCatalog',
function(scope, params, appcatalog) {
var catalog = appcatalog;
scope.appcatalog = catalog;
var id = params.id;
for(var i = 0; i < catalog.apps.length; i++) {
var app = catalog.apps[i];
if(app.id == params.id) {
scope.app = app;
return;
}
}
}
]);
The major difference here is in how the factory is set up. It's not constructing a new object in the controller, but rather using dependency injection to put the factory into the scope of the controllers. This is example is working with a list and 3 controllers which all share the appcatalog factory. This is working very nicely now.
I'm still not sure about the best way to remember my location in the scroll area and make sure it returns to the same spot when coming from detail and returning to the list.

Resources