I am trying to add to a list in a home.html and display the list in myOrders.html using ionic and angularjs.
The problem is that when I push a new item to the array, the previous items get replaced with the new item.
Example:
push 'one' -> array is [{'name':one'}]
push 'two' -> array is [{'name':'two'},{'name':'two'}] // should be
[{'name':'one'},{'name':'two'}]
push 'three' -> array is [{'name':'three'}, {'name':'three'},
{'name':'three'}] // should be
[{'name':'one'},{'name':'two'},{'name':'three'}]
I have added the relevant parts of my code below.
home.html (Add to list)
<ion-view title="Home">
<ion-content ng-controller="homeCtrl">
<form ng-submit="submitForm(product)" class="list">
<input ng-model="product.name" type="text">
<input type="submit" value="Search" class="button">
</form>
</ion-content>
</ion-view>
myOrders.html (Display list)
<ion-view title="My Orders">
<ion-content ng-controller="myOrdersCtrl">
{{ product }}
</ion-content>
</ion-view>
controllers.js
angular.module('app.controllers', [])
...
.controller('homeCtrl', function($scope, $state, formData) {
$scope.product = {};
$scope.submitForm = function(product) {
if (product.name) {
formData.updateForm(product);
$state.go('menu.myOrders');
} else {
alert("Please fill out some information for the user");
}
};
})
.controller('myOrdersCtrl', function($scope, formData) {
$scope.product = formData.getForm();
})
services.js
angular.module('app.services', [])
.service('formData', [function(){
return {
form: [],
getForm: function() {
return this.form;
},
updateForm: function(item) {
this.form.push(item);
}
}
}]);
You are inserting same object again and again into the array. As objects are always pass-by-reference so, reference of same object is pushed into array. When you update the object all references stored in array are changed.
Try something like creating copy of your object, while passing to updateForm()
.controller('homeCtrl', function($scope, $state, formData) {
$scope.product = {};
$scope.submitForm = function(product) {
if (product.name) {
formData.updateForm(angular.copy(product));
$state.go('menu.myOrders');
} else {
alert("Please fill out some information for the user");
}
};
})
Related
I'm new to Ionic. I write code for list. List is working perfectly but when click on any list-item it's not showing any data.
It showing me this error "Cannot GET /pilliondetails/1" how can i solve this?
app.factory('myService', function() {
var savedData = {}
function set(data) {
savedData = data;
console.log(savedData);
}
function get() {
return savedData;
}
return {
set: set,
get: get
}
})
PillionList Controller:
.controller('PillionListCtrl',function($scope,$ionicHistory,myService){
$scope.myGoBack = function() {
$ionicHistory.goBack();
};
$scope.pillions = [];
var promise=myService.get();
$scope.pillions=myService.get();
})
PillionDetail Controller:
.controller('PillionDetailCtrl',function($scope, $ionicHistory, $stateParams, myService)
{
$scope.myGoBack = function() {
$ionicHistory.goBack();
};
var promise=myService.get($stateParams.requestId);
console.log(promise);
})
PillionList.html :Showing list pf Pillions
<ion-list>
<ion-item data-ng-repeat="pillion in pillions">
<div class="list list-inset">
{{pillion.request_departure_date}}-{{pillion.request_departure_time}}
{{pillion.request_from}} >> {{pillion.request_to}}
{{pillion.user_first_name}} {{pillion.user_last_name}}
<a ui-sref="pilliondetails({pillionId:pillion.request_id})" nav-direction="enter">
<h2>More Details...</h2>
</a>
</div>
</ion-item>
</ion-list>
my app.js
.state('pillionlist', {
url: '/pillionlist',
templateUrl: 'templates/pillionlist.html',
controller: 'PillionListCtrl'
})
.state('pilliondetails', {
url: '/pillionlist/:pillionId',
templateUrl: 'templates/pilliondetails.html',
controller: 'PillionDetailCtrl'
})
Its redirecting to pillionDetail view but not showing data.
Please help.
The first thing i noticed is
ui-sref="pilliondetails({pillion.request_id})"
it should be key-value pair like this
ui-sref="pilliondetails({ your_id : pillion.request_id})"
and in stateProvider, the url of details page should contain parameter. for eg.
url : '/pilliondetails/:your_id'
I made a simple AnguarJS app with form and list of books. In list of books I have a form, in which I can type information about book and submit, and my list of book should change. I want to make something like this: http://www.w3schools.com/angular/tryit.asp?filename=try_ng_app4
But when I add information in form, I don't see added infromatioin in book-list, but only empty field. I don't want to send information to the server, I only want to see added information on the web-page. Files, that I use are below:
app.js
var module = angular.module("sampleApp", ['ngRoute']);
module.config(function ($interpolateProvider) {
$interpolateProvider.startSymbol('[[').endSymbol(']]');
})
module.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/route1', {
templateUrl: 'static/myapp/html/test1.html',
controller: 'RouteController1'
}).
when('/route2', {
templateUrl: 'static/myapp/html/test2.html',
controller: 'BookController'
}).
otherwise({
redirectTo: '/'
});
}]);
module.controller('BookController', ['$scope', function($scope) {
$scope.books = [
{
title: 'test',
author: 'test',
}
];
$scope.addMe = function (title, author) {
$scope.books.push({title: title, author: author});
}
}]);
test2.html
<div class="container">
<div ng-controller="BookController" >
<ul>
<li ng-repeat = "book in books">
Title:<p>[[book.title]] </p>
Author: <p>[[book.author]] </p>
</li>
</ul>
<input type="text" placeholder = 'title'/>
<input type="text" placeholder = 'author'/>
<button ng-click="addMe(title,author)">Add</button>
</div>
</div>
After filling form I get the next result:
It does not work because you don't set variable.
You add title and author in addMe but if you console.log these variables, it shows undefined.
You can use $scope. You can see it as the bridge between the controller and the view. So, in your view, when you set the title and the author and click on addMe, you will get it in the controller in $scope.title and scope.author
in the view.
<input type="text" placeholder = 'title' ng-model="title"/>
<input type="text" placeholder = 'author' ng-model="author"/>
<button ng-click="addMe()">Add</button>
In the controller just after the books declaration:
$scope.title = '';
$scope.author = '';
In addMe
$scope.books.push({title: $scope.title, author: $scope.author});
Try setting $scope.books to a new array instead of pushing to it. Angular.js checks which variables have changed by comparing references. Since the variable book stays set to the same array, angular's dirty checking feature might not detect a new element.
Change it to something like this
$scope.books = $scope.books.concat([{title: title, author: author}]);
This should work because concat returns a new array instead of updating the old one.
I have an angular.js / ionic framework app. That loads recipes in a list and allows the user to save any recipe they want. The problem is that the first time someone clicks save, nothing happens but on the second time onwards, the recipe is actually saved. This is because the variable is not loaded the first time someone clicks save and it is only loaded after the first click is made. How can I fix my code to get it to save the first time I click save?
Here is what my html looks like:
<ion-content has-header="true" padding="true" overflow-scroll="true">
<input type="text" ng-model="searchString" placeholder="Search using recipe title ..." />
<ion-list can-swipe="true">
<ion-item class="item item-thumbnail-left" ng-repeat="recipeItem in remoteRecipeList| searchFor:searchString" type="item-text-wrap"
href="#/tab/browse/{{recipeItem.id}}">
<img ng-src="{{recipeItem.get('picture').url()}}">
<div><strong>{{recipeItem.get('title')}}</strong></div>
<div class="">{{recipeItem.get('description')}}</div>
<ion-option-button class="button-balanced" ng-click="doSaveRow(recipeItem.id)">
Save
</ion-option-button>
</ion-item>
</ion-list>
</ion-content>
And here is what my controller (javascript) looks like:
.controller('BrowseCtrl', function (user, $state, $scope, RecipeService, $cordovaCamera, $ionicPopup, $timeout, ParseRecipeService, ParseConfiguration, UserService, $cordovaSQLite) {
$scope.count = 0;
// if not using parse then assign the image service to the default
// service
if (ParseConfiguration.USING_PARSE === false) {
ParseRecipeService = RecipeService;
console.log("ParseConfiguration: " + ParseConfiguration.USING_PARSE);
}
ParseRecipeService.all().then(function (_data) {
$timeout($scope.remoteRecipeList = _data, 0);
console.log(JSON.stringify(_data));
}, function (_error) {
console.error(JSON.stringify(_error));
alert(_error.message)
});
// Save the selected recipe to SQL database
$scope.doSaveRow = function (_index) {
$scope.count++;
ParseRecipeService.get(_index).then(function (_data) {
$timeout($scope.recipeItem = _data, 0);
}, function (_error) {
console.error(_error.message);
});
var query = "INSERT INTO recipetable (id, instructions, title, description, num_serves, recipe_type, time_in_minutes, picture, ingredients) VALUES (?,?,?,?,?,?,?,?,?)";
$cordovaSQLite.execute(db, query, [null, $scope.recipeItem.get('instructions'), $scope.recipeItem.get('title'), $scope.recipeItem.get('description'), $scope.recipeItem.get('num_serves'), $scope.recipeItem.get('recipe_type'), $scope.recipeItem.get('time_in_minutes'), $scope.recipeItem.get('picture').url(), $scope.recipeItem.get('ingredients')]).then(function(res) {
alert("The recipe has been saved to your device");
}, function (err) {
console.error(err);
});
$scope.searchTitles = true;
$scope.searchDescriptions = true;
$scope.$watch('searchTitles', function(){
$scope.searchKeys = [ $scope.searchTitles ? 'title' : null, $scope.searchDescriptions ? 'description' : null ];
});
$scope.$watch('searchTitles', function(){
$scope.searchKeys = [ $scope.searchTitles ? 'title' : null, $scope.searchDescriptions ? 'description' : null ];
});
};
})
I am trying to return an object, taht I populate in a forEach loop, with angulars $scope from a controller, but when I try to loop it out with ng-repeat I get no result.
When i console.log the object I get the expected result
But when I try to return it with $scope and show it with ng-repeat I get no results what so ever.
Here is my controller
myAppControllers.controller('musicCtrl', ['$scope', '$http', function($scope, $http) {
var i = 0,
playlists = {};
// Get the playlists from soundcloud
$http({ method: 'GET', url: 'http://api.soundcloud.com/users/gimle-sound-tjek/playlists.json?client_id=c2dfe07de1d18d689516884ce22b7aae' }).
success(function(data) {
data.forEach(function() {
// Populate the object
playlists[i] = {
"title" : data[i].title,
"permalink": data[i].permalink,
"genre": data[i].genre
}
i++;
});
console.log(playlists);
$scope.playlists;
}).
error(function() {
$scope.playlists = '';
});
}]);
My ng-repeat looks like this
<div ng-repeat="playlist in playlists">
<h3>{{ playlist.title }}</h3>
...
I am expecting that is has something to do with the way I send the object back with $scope.playlists?
First of all maybe use push instead this i++ fun.
You push those playlist entries into the playlist variable outside the scope.
myAppControllers.controller('musicCtrl', ['$scope', '$http', function($scope, $http) {
$scope.playlists= [];
// Get the playlists from soundcloud
$http({ method: 'GET', url: 'http://api.soundcloud.com/users/gimle-sound-tjek/playlists.json?client_id=c2dfe07de1d18d689516884ce22b7aae' }).
success(function(data) {
data.forEach(function(entry) {
// Populate the object
$scope.playlists.push({
"title" : entry.title,
"permalink": entry.permalink,
"genre": entry.genre
});
//OR: $scope.playlists.push(entry);
});
}).
error(function() {
$scope.playlists = '';
});
}]);
What if you try $scope.playlists = [] instead of var playlist = {}
Overview
I am building an app (running on MAMP) that holds contact information that will expand to hold more data such as project name & deadline, once this part is functional.
Questions
When the user visits /projects.php#/project/ I would like them to see a list of all the project names with a link to their detail page.
How should I write the following to access all of my data?
Do I need the .json at the end?
What does the #id do?
return $resource('data/project.json/:id', {id: '#id'});
When the user visits /projects.php#/project/a-gran-goodn I would like them to see the details about this project(for now, just the name & address).
How should I write the following to return my data by Id?
$scope.project = $routeParams.id ? Project.get({id: $routeParams.id}): new Project();
plunkr file
http://plnkr.co/edit/7YPBog
project.json
This file lives on http://localhost:8888/angularjs/ProjectsManager/data/project.json
[
{ "address" : [ " 3156 Dusty Highway",
" Teaneck New Jersey 07009-6370 US"
],
"id" : "a-gran-goodn",
"name" : "Grania Goodner",
"phone" : " (862) 531-9163"
},
{ "address" : [ " 62 Red Fawn Moor",
" Rodney Village West Virginia 25911-8091 US"
],
"id" : "b-aime-defranc",
"name" : "Aimery Defranco",
"phone" : " (681) 324-9946"
}
]
app.js
var projectsApp = angular.module('projects', ['ngResource']);
projectsApp.config(function($routeProvider) {
$routeProvider
.when('/', {
controller: 'ProjectListCtrl',
templateUrl: 'partials/projectlist.html'})
.when('project/:id', {
controller: 'ProjectDetailCtrl',
templateUrl: 'partials/projectdetail.html'
})
.otherwise('/');
});
projectsApp.factory('Project', function($resource) {
return $resource('data/project.json/:id', {id: '#id'});
});
projectsApp.controller('ProjectListCtrl', function(Project, $scope) {
$scope.projects = Project.query();
console.log($scope.projects);
});
projectsApp.controller('ProjectDetailCtrl', function(Project, $routeParams, $scope) {
$scope.project = $routeParams.id
? Project.get({id: $routeParams.id})
: new Project();
});
partials/projectlist.html
Add new item
<ul class="unstyled">
<li ng-repeat="project in projects">
<div class="well">
<h2><small>{{project.id}}</small> {{project.name}}</h2>
View Info for {{project.name}}
</div>
</li>
</ul>
partials/projectdetails.html
<h3>Information</h3>
<p>Name: {{project.name}}</p>
<p>Phone Number: {{project.phone}}</p>
<p ng-repeat="line in project.address">{{line}}</p>
index.php
<?php
header('Access-Control-Allow-Origin: *');
?>
<!doctype html>
<html ng-app="projects">
<head>
<meta charset="utf-8">
<title ng-bind="title" ng-cloak>Restaurant —</title>
<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
</head>
<body ng-controller="ProjectListCtrl">
<a class="brand" href="#">Projects Manager</a>
<div id="app-container" class="container-fluid">
<div class="row-fluid">
<div class="span12" id="main" ng-view>
</div><!--/.span12-->
</div><!--/.row-fluid-->
<footer>Copyright Projects © 2013</footer>
</div><!--/.container-->
<script src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<!-- Don't forget to load angularjs AND angular-resource.js -->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular-resource.js></script>
<!--Controllers-->
<script src="app.js"></script>
</body>
</html>
Since you can't query against a raw JSON file like you can with RESTful-style URLs (which is what $resource is built to do), you can instead get a copy of the JSON and then build your own query, get, etc. that looks at the data and returns the right thing. It's a bit tricky because you also want to support new Project, which doesn't really make sense when using a file-backed store, but this example supports it:
projectsApp.factory('Project', function($http) {
// Create an internal promise that resolves to the data inside project.json;
// we'll use this promise in our own API to get the data we need.
var json = $http.get('project.json').then(function(response) {
return response.data;
});
// A basic JavaScript constructor to create new projects;
// passed in data gets copied directly to the object.
// (This is not the best design, but works for this demo.)
var Project = function(data) {
if (data) angular.copy(data, this);
};
// The query function returns an promise that resolves to
// an array of Projects, one for each in the JSON.
Project.query = function() {
return json.then(function(data) {
return data.map(function(project) {
return new Project(project);
});
})
};
// The get function returns a promise that resolves to a
// specific project, found by ID. We find it by looping
// over all of them and checking to see if the IDs match.
Project.get = function(id) {
return json.then(function(data) {
var result = null;
angular.forEach(data, function(project) {
if (project.id == id) result = new Project(project);
});
return result;
})
};
// Finally, the factory itself returns the entire
// Project constructor (which has `query` and `get` attached).
return Project;
});
You can use the results of query and get like any other promise:
projectsApp.controller('ProjectListCtrl', function(Project, $scope) {
$scope.projects = Project.query();
});
projectsApp.controller('ProjectDetailCtrl', function(Project, $routeParams, $scope) {
$scope.project = $routeParams.id
? Project.get($routeParams.id)
: new Project();
});
Note the change to Project.get($routeParams.id); also, the updated Plunker also fixes a problem in your $routeProvider configuration.
This is all demonstrated here: http://plnkr.co/edit/mzQhGg?p=preview
i will paste here a generic code i use to fetch json from your local or a remoteserver maybe it will help you:
it uses a factory that you can call when you need it.
app.factory('jsonFactory', function($http) {
var jsonFactory= {
fromServer: function() {
var url = 'http://example.com/json.json';
var promise = $http.jsonp(url).then(function (response) {
return response.data;
});
return promise;
},
hospitals: function() {
var url = 'jsons/hospitals.js';
var promise = $http.get(url).then(function (response) {
return response.data;
});
return promise;
}
};
return jsonFactory;
});
Then when you need to call it:
function cardinalCtrl(jsonFactory, $scope, $filter, $routeParams) {
jsonFactory.hospitals().then(function(d){
$scope.hospitals=d.hospitals;
});
jsonFactory.fromServer().then(function(d){
$scope.fromServer=d.hospitals;
});
}