JSON request with Angular Displays an Empty Response - javascript

I believe Angular is loading the page before it receives all the information from JSONP. If I refresh the page a couple of times I do get the information to display; however, it is not constant. My code is almost the same as the code I am using on my projects page which does not have the same issue.
HTML:
<div class="container">
<div class="row push-top" ng-show="user">
<div class="col-xs-10 col-xs-offset-1 col-sm-10 col-sm-offset-1 col-md-10 col-md-offset-1">
<div class="well well-sm">
<div class="row">
<div class="col-sm-3 col-md-2">
<img ng-src="[[ user.images.138 ]]" alt="" class="img-rounded img-responsive" />
</div>
<div class="col-sm-7 col-md-8">
<h4 ng-bind="user.display_name"></h4>
<h5 ng-bind="user.occupation"></h5>
<i class="fa fa-map-marker"></i>
<cite title="[[ user.city ]], [[ user.country ]]">[[ user.city ]], [[ user.country ]]</cite>
<br>
<strong ng-bind="user.stats.followers"></strong> Followers, <strong ng-bind="user.stats.following"></strong> Following
<hr>
<p style="margin-top:10px;" ng-bind="user.sections['About Me']"></p>
</div>
</div>
</div>
</div>
</div>
</div>
JavaScipt:
'use strict';
angular.module('angularApp')
.controller('AboutCtrl', function ($scope, $window, Behance) {
$scope.loading = true;
Behance.getUser('zachjanice').then(function (user) {
$scope.user = user;
$scope.loading = false;
}, function (error) {
console.log(error);
$scope.loading = false;
$scope.user = null;
});
$scope.gotoUrl = function (url) {
$window.location.href = url;
};
});
You can see the page in question at: http://zachjanice.com/index.html#/about. Thanks in Advance.
As requested here is the behance service:
'use strict';
angular.module('angularApp')
.factory('Behance', function ($http, $q, localStorageService, BEHANCE_CLIENT_ID) {
// Should be called to refresh data (for testing purposes)
// localStorageService.clearAll();
// Public API
return {
// Get a list of projects
getProjects: function (config) {
var pageNum = 1;
if (angular.isObject(config) && angular.isDefined(config.page)) {
pageNum = config.page;
}
var _projects = $q.defer(),
_storedProjects = localStorageService.get('Projects_Page_');
if (_storedProjects !== null) {
_projects.resolve(_storedProjects);
} else {
$http.jsonp('https://www.behance.net/v2/users/zachjanice/projects', {
params: {
'client_id': BEHANCE_CLIENT_ID,
'callback': 'JSON_CALLBACK',
'page': pageNum
}
})
.then(function (response) {
if (response.data.http_code === 200 && response.data.projects.length > 0) {
// console.log('getting page', _page);
_projects.resolve(response.data.projects);
localStorageService.add('Projects_Page_' + pageNum, response.data.projects);
}
});
}
return _projects.promise;
},
// Get project with id
getProject: function (id) {
var _project = $q.defer();
$http.jsonp('https://www.behance.net/v2/projects/' + id, {
params: {
'client_id': BEHANCE_CLIENT_ID,
'callback': 'JSON_CALLBACK'
},
cache: true
}).success(function (data){
_project.resolve(data.project);
});
return _project.promise;
},
// Get project with id
getUser: function (username) {
var _user = $q.defer();
$http.jsonp('https://www.behance.net/v2/users/' + username, {
params: {
'client_id': BEHANCE_CLIENT_ID,
'callback': 'JSON_CALLBACK'
},
cache: true
}).success(function (data){
_user.resolve(data.user);
});
return _user.promise;
}
};
});

Anthony Chu supplied no support, so I found the answer myself. The issue was not the Behance Service, but the Projects Controller like I had originally stated.
I changed $scope.loading under the call for the service from false to true. Works every time.

Related

Failed to instantiate module angularApp due to

I have this bug when I work authentification between angular js and symfony , I have bug in front end (angular js) :
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.6.5/$injector/modulerr?p0=angularApp&p1=Error%3A%20%5B%24injector%3Amodulerr%5D%20http%3A%2F%2Ferrors.angularjs.org%2F1.6.5%2F%24injector%2Fmodulerr%3Fp0%3Drestangular%26p1%3DTypeError%253A%2520Cannot%2520read%2520property%2520'isUndefined'%2520of%2520undefined%250A%2520%2520%2520%2520at%2520Object.Configurer.init%2520(http%253A%252F%252Flocalhost%252Ftestauthenti%252Fnode_modules%252Frestangular%252Fdist%252Frestangular.js%253A42%253A29)%250A%2520%2520%2520%2520at%2520new%2520%253Canonymous%253E%2520(http%253A%252F%252Flocalhost%252Ftestauthenti%252Fnode_modules%252Frestangular%252Fdist%252Frestangular.js%253A812%253A16)%250A%2520%2520%2520%2520at%2520Object.instantiate%2520(https%253A%252F%252Fcdnjs.cloudflare.com%252Fajax%252Flibs%252Fangular.js%252F1.6.5%252Fangular.min.js%253A44%253A458)%250A%2520%2520%2520%2520at%2520c%2520(https%253A%252F%252Fcdnjs.cloudflare.com%252Fajax%252Flibs%252Fangular.js%252F1.6.5%252Fangular.min.js%253A41%253A370)%250A%2520%2520%2520%2520at%2520Object.provider%2520(https%253A%252F%252Fcdnjs.cloudflare.com%252Fajax%252Flibs%252Fangular.js%252F1.6.5%252Fangular.min.js%253A41%253A312)%250A%2520%2520%2520%2520at%2520d%2520(https%253A%252F%252Fcdnjs.cloudflare.com%252Fajax%252Flibs%252Fangular.js%252F1.6.5%252Fangular.min.js%253A42%253A237)%250A%2520%2520%2520%2520at%2520https%253A%252F%252Fcdnjs.cloudflare.com%252Fajax%252Flibs%252Fangular.js%252F1.6.5%252Fangular.min.js%253A42%253A358%250A%2520%2520%2520%2520at%2520p%2520(https%253A%252F%252Fcdnjs.cloudflare.com%252Fajax%252Flibs%252Fangular.js%252F1.6.5%252Fangular.min.js%253A8%253A7)%250A%2520%2520%2520%2520at%2520g%2520(https%253A%252F%252Fcdnjs.cloudflare.com%252Fajax%252Flibs%252Fangular.js%252F1.6.5%252Fangular.min.js%253A42%253A138)%250A%2520%2520%2520%2520at%2520https%253A%252F%252Fcdnjs.cloudflare.com%252Fajax%252Flibs%252Fangular.js%252F1.6.5%252Fangular.min.js%253A42%253A322%0A%20%20%20%20at%20https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fangular.js%2F1.6.5%2Fangular.min.js%3A7%3A76%0A%20%20%20%20at%20https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fangular.js%2F1.6.5%2Fangular.min.js%3A43%3A70%0A%20%20%20%20at%20p%20(https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fangular.js%2F1.6.5%2Fangular.min.js%3A8%3A7)%0A%20%20%20%20at%20g%20(https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fangular.js%2F1.6.5%2Fangular.min.js%3A42%3A138)%0A%20%20%20%20at%20https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fangular.js%2F1.6.5%2Fangular.min.js%3A42%3A322%0A%20%20%20%20at%20p%20(https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fangular.js%2F1.6.5%2Fangular.min.js%3A8%3A7)%0A%20%20%20%20at%20g%20(https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fangular.js%2F1.6.5%2Fangular.min.js%3A42%3A138)%0A%20%20%20%20at%20gb%20(https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fangular.js%2F1.6.5%2Fangular.min.js%3A46%3A251)%0A%20%20%20%20at%20c%20(https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fangular.js%2F1.6.5%2Fangular.min.js%3A22%3A19)%0A%20%20%20%20at%20Uc%20(https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fangular.js%2F1.6.5%2Fangular.min.js%3A22%3A332)
and this is link error:
https://docs.angularjs.org/error/$injector/unpr?p0=RestangularProvider%20%3C-%20Restangular%20%3C-%20MainCtrl
code index.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<!-- <link rel="stylesheet" href="styles/main.css"> -->
</head>
<body ng-app="angularApp">
<div class="container">
<div ng-include="'main.html" ng-controller="MainCtrl"></div>
<div ui-view></div>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
--> <script src="../node_modules/angular/angular.js"></script>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/js/bootstrap.js"></script>
-->
<script src="../node_modules/restangular/dist/restangular.js"></script>
<script src="../node_modules/lodash/lodash.js"></script>
<script src="app.js"></script>
<script src="main.js"></script>
</body>
</html>
code main.html:
<!—Displays error or success messages-->
<span>{{message}}</span><br><br>
<!—Login/logout form-->
<form ng-show="!isAuthenticated" ng-submit="submit()">
<label>Login Form:</label><br>
<input ng-model="user.username" type="text" name="user" placeholder="Username" disabled="true" />
<input ng-model="user.password" type="password" name="pass" placeholder="Password" disabled="true" />
<input type="submit" value="Login" />
</form>
<div ng-show="isAuthenticated">
<a ng-click="logout()" href="">Logout</a>
</div>
<div ui-view ng-show="isAuthenticated"></div>
<br><br>
<!—Displays contacts list-->
<h1 ng-show="isAuthenticated">Liste des Contacts</h1>
<article ng-repeat="contact in contacts" ng-show="isAuthenticated" id="{{ contact['#id'] }}" class="row marketing">
<h2>{{ contact.nom }}</h2>
<!—Displays contact phones list-->
<h3 ng-repeat="moyenComm in contact.moyensComm">Tél : {{ moyenComm.numero }}</h3>
</article><hr>
<!—Create contact form-->
<form name="createContactForm" ng-submit="createContact(createContactForm)" ng-show="isAuthenticated" class="row marketing">
<h2>Création d'un nouveau contact</h2>
<!—Displays error / success message on creating contact-->
<div ng-show="contactSuccess" class="alert alert-success" role="alert">Contact publié.</div>
<div ng-show="contactErrorTitle" class="alert alert-danger" role="alert">
<b>{{ contactErrorTitle }}</b><br>
{{ contactErrorDescription }}
</div>
<div class="form-group">
<input ng-model="newContact.nom" placeholder="Nom" class="form-control">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<!—Phone form-->
<form name="createPhoneForm" ng-submit="createPhone(createPhoneForm)" ng-show="isAuthenticated" class="row marketing">
<h2>Création d'un nouveau téléphone</h2>
<div ng-show="phoneSuccess" class="alert alert-success" role="alert">Téléphone publié.</div>
<div ng-show="phoneErrorTitle" class="alert alert-danger" role="alert">
<b>{{ phoneErrorTitle }}</b><br>
{{ phoneErrorDescription }}
</div>
<div class="form-group">
<input ng-model="newPhone.numero" placeholder="Numéro" class="form-control">
</div>
<div class="form-group">
<label for="contact">Contact</label>
<!—SelectBox de liste de contacts-->
<select ng-model="newPhone.contact" ng-options="contact['#id'] as contact.nom for contact in contacts" id="contact"></select>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
code app.js:
'use strict';
var app = angular
.module('angularApp', ['restangular'])
app.config(['RestangularProvider', function (RestangularProvider) {
// URL ENDPOINT TO SET HERE !!!
RestangularProvider.setBaseUrl('http://your_vhost/api');
RestangularProvider.setRestangularFields({
id: '#id'
});
RestangularProvider.setSelfLinkAbsoluteUrl(false);
RestangularProvider.addResponseInterceptor(function (data, operation) {
function populateHref(data) {
if (data['#id']) {
data.href = data['#id'].substring(1);
}
}
populateHref(data);
if ('getList' === operation) {
var collectionResponse = data['hydra:member'];
collectionResponse.metadata = {};
angular.forEach(data, function (value, key) {
if ('hydra:member' !== key) {
collectionResponse.metadata[key] = value;
}
});
angular.forEach(collectionResponse, function (value) {
populateHref(value);
});
return collectionResponse;
}
return data;
});
}])
;
code main.js:
'use strict';
var app = angular
.module('angularApp')
app.controller('MainCtrl', function ($scope, $http, $window, Restangular) {
// fosuser user
$scope.user = {username: 'johndoe', password: 'test'};
// var to display login success or related error
$scope.message = '';
// In my example, we got contacts and phones
var contactApi = Restangular.all('contacts');
var phoneApi = Restangular.all('telephones');
// This function is launched when page is loaded or after login
function loadContacts() {
// get Contacts
contactApi.getList().then(function (contacts) {
$scope.contacts = contacts;
});
// get Phones (throught abstrat CommunicationWays alias moyensComm)
phoneApi.getList().then(function (phone) {
$scope.phone = phone;
});
// some vars set to default values
$scope.newContact = {};
$scope.newPhone = {};
$scope.contactSuccess = false;
$scope.phoneSuccess = false;
$scope.contactErrorTitle = false;
$scope.contactErrorDescription = false;
$scope.phoneErrorTitle = false;
$scope.phoneErrorDescription = false;
// contactForm handling
$scope.createContact = function (form) {
contactApi.post($scope.newContact).then(function () {
// load contacts & phones when a contact is added
loadContacts();
// show success message
$scope.contactSuccess = true;
$scope.contactErrorTitle = false;
$scope.contactErrorDescription = false;
// re-init contact form
$scope.newContact = {};
form.$setPristine();
// manage error handling
}, function (response) {
$scope.contactSuccess = false;
$scope.contactErrorTitle = response.data['hydra:title'];
$scope.contactErrorDescription = response.data['hydra:description'];
});
};
// Exactly same thing as above, but for phones
$scope.createPhone = function (form) {
phoneApi.post($scope.newPhone).then(function () {
loadContacts();
$scope.phoneSuccess = true;
$scope.phoneErrorTitle = false;
$scope.phoneErrorDescription = false;
$scope.newPhone = {};
form.$setPristine();
}, function (response) {
$scope.phoneSuccess = false;
$scope.phoneErrorTitle = response.data['hydra:title'];
$scope.phoneErrorDescription = response.data['hydra:description'];
});
};
}
// if a token exists in sessionStorage, we are authenticated !
if ($window.sessionStorage.token) {
$scope.isAuthenticated = true;
loadContacts();
}
// login form management
$scope.submit = function() {
// login check url to get token
$http({
method: 'POST',
url: 'http://your_vhost/login_check',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: $.param($scope.user)
// with success, we store token to sessionStorage
}).success(function(data) {
$window.sessionStorage.token = data.token;
$scope.message = 'Successful Authentication!';
$scope.isAuthenticated = true;
// ... and we load data
loadContacts();
// with error(s), we update message
}).error(function() {
$scope.message = 'Error: Invalid credentials';
delete $window.sessionStorage.token;
$scope.isAuthenticated = false;
});
};
// logout management
$scope.logout = function () {
$scope.message = '';
$scope.isAuthenticated = false;
delete $window.sessionStorage.token;
};
// This factory intercepts every request and put token on headers
})
app.factory('authInterceptor', function($rootScope, $q, $window) {
return {
request: function (config) {
config.headers = config.headers || {};
if ($window.sessionStorage.token) {
config.headers.Authorization = 'Bearer ' + $window.sessionStorage.token;
}
return config;
},
response: function (response) {
if (response.status === 401) {
// if 401 unauthenticated
}
return response || $q.when(response);
}
};
// call the factory ...
})
app.config(function ($httpProvider) {
$httpProvider.interceptors.push('authInterceptor');
});
help me please for resolve this bug and thanks advanced
I think isUndefined is a function in underscore.js, which is a dependency of Restangular:
http://underscorejs.org/#isUndefined
Do you have underscore.js included in your assets?

Angular: ng-repeat calculate data in view

I am writing an angular website, but I have the following problem. I have 2 data arrays that I get from my json files.
I use an ng-repeat to go over my projects in my html file, and I use another ng-repeat to go over my projects.languages.
Now what I want to do is to make it that for every language I find I am going to search in the languages data
and get the other information.
How can I easly get the language in the ng-repeat, I need to also calculate in that the data maybe not avaible yet,
because I get the json data async.
This is the code I have right now:
<div class="container-fluid contentcontainer">
<div class="row">
<div class="col-xs-6 col-md-3" ng-repeat="project in projects">
<a href="#/project/{{$index}}" class="thumbnail">
<img ng-src="{{project.img}}" ng-alt="{{project.name}}" />
<div class="caption">
<div class="languageoverlay">
<span ng-repeat="language in projects[$index].languages">
<img ng-src="img/languages/android.png" ng-alt="{{language}}" />
<font ng-show="!$last">+</font>
</span>
</div>
<h3>{{project.name}}</h3>
</div>
</a>
</div>
</div>
</div>
<!--this is just to try, don't need to use this-->
<h1>{{getLanguage("CSharp")}}</h1>
App.js
app.service('projectService', ['$http', '$q', function($http, $q) {
var projectsDeferred = $q.defer();
var languagesDeferred = $q.defer();
$http({
method: 'POST',
url: 'json/projects.json',
cache: true
}).then(function(data) {
projectsDeferred.resolve(data.data.projects);
});
$http({
method: 'POST',
url: 'json/projects.json',
cache: true
}).then(function(data) {
languagesDeferred.resolve(data.data.languages);
});
this.getProjects = function(){
return projectsDeferred.promise;
};
this.getLanguages = function(){
return languagesDeferred.promise;
};
}]);
app.controller('ProjectsController', ['$scope', 'projectService', function($scope, projectService) {
$scope.projects = {};
$scope.languages = {};
var promise = projectService.getProjects();
promise.then(function(data) {
$scope.projects = data;
});
var promise = projectService.getLanguages();
promise.then(function(data) {
$scope.languages = data;
});
// This was a try, don't need to use this
$scope.getLanguage = function(name) {
array.forEach(function(element) {
if (element.name == name) {
$scope.push(element);
}
}, $scope.languages);
};
}]);
languages.json
{
"result":"SUCCESS",
"resultMessage":"",
"languages":[
{
"name":"CSharp",
"FullName":"C#",
"img":"img/languages/csharp.png"
},
{
"name":"Android",
"FullName":"Android",
"img":"img/languages/android.png"
},
{
"name":"VisualStudio",
"FullName":"Visual Studio",
"img":"img/languages/visualstudio.png"
}
]
}
projects.json
{
"result":"SUCCESS",
"resultMessage":"",
"projects":[
{
"name":"Test1",
"img":"img/projects/photo-1453060113865-968cea1ad53a.jpg",
"languages":["Android"]
},
{
"name":"Test2",
"img":"img/projects/photo-1454165205744-3b78555e5572.jpg",
"languages":["Android"]
},
{
"name":"Test3",
"img":"img/projects/photo-1457305237443-44c3d5a30b89.jpg",
"languages":["CSharp","VisualStudio"]
},
{
"name":"Test4",
"img":"img/projects/photo-1457612928689-a1ab27da0dad.jpg",
"languages":["CSharp","VisualStudio"]
}
]
}
Easy piece:
First don't use $q just use $http
app.service('projectService', ['$http', '$filter', function($http, $filter) {
function callLanguages(languages) {
return $http({
method: 'GET',
url: 'json/projects.json',
cache: true
}).then(function (response) {
return buildProjectWithLanguages(response.data.projects, languages);
});
}
function buildProjectWithLanguages (projects, languages) {
return projects.map(function (p) {
var langs = p.languages.map(function (l) {
var matchLangs = $filter('filter')(languages, { name: l });
if (matchLangs.length) {
return matchLangs[0];
} else {
return { FullName: l };
}
});
p.languages = langs;
return p;
});
}
this.getProjects = function(){
return $http({
method: 'GET',
url: 'json/languages.json',
cache: true
}).then(function(response) {
return callLanguages(response.data.languages);
});
};
}]);
then simplify your controller
app.controller('ProjectsController', ['$scope', 'projectService', function($scope, projectService) {
$scope.projects = [];
projectService.getProjects(function (projects) {
$scope.projects = projects;
});
}]);
and finally change your html to this:
<div class="container-fluid contentcontainer">
<div class="row">
<div class="col-xs-6 col-md-3" ng-repeat="project in projects">
<a href="#/project/{{$index}}" class="thumbnail">
<img ng-src="{{project.img}}" ng-alt="{{project.name}}" />
<div class="caption">
<div class="languageoverlay">
<span ng-repeat="language in project.languages">
<img ng-src="{{language.img}}" ng-alt="{{language.FullName}}" />
<font ng-show="!$last">+</font>
</span>
</div>
<h3>{{project.name}}</h3>
</div>
</a>
</div>
</div>
</div>
I really loved your awnser, but I made another approach with directives. I tested your awnser and it looks like a correct awnser.
This is what I did:
projects-directive.html
<div class="row">
<div class="col-xs-6 col-md-3" ng-repeat="project in projects">
<a href="#/project/{{$index}}" class="thumbnail">
<img ng-src="{{project.img}}" ng-alt="{{project.name}}" />
<div class="caption">
<languages languagenames="project.languages"></languages>
<h3>{{project.name}}</h3>
</div>
</a>
</div>
</div>
languages-directive.html
<div class="languageoverlay">
<span ng-repeat="language in languages">
<img ng-src="{{language.img}}" ng-alt="{{language.FullName}}" />
<font ng-show="!$last">+</font>
</span>
</div>
app.js
app.service('projectService', ['$http', '$filter', function($http, $filter) {
this.getLanguages = function() {
return $http({
method: 'GET',
url: 'json/languages.json',
cache: true
});
}
this.getProjects = function(){
return $http({
method: 'GET',
url: 'json/projects.json',
cache: true
})
};
}]);
app.directive('projects', ['projectService', function(projectService) {
return {
restrict: 'E',
templateUrl: "directives/projects-directive.html",
scope: {
limitto: "=?"
},
controller: function($scope)
{
projectService.getProjects().then(function(response) {
projects = response.data.projects;
if (angular.isDefined($scope.limitto))
{
$scope.projects = projects.slice(0, $scope.limitto);
} else {
$scope.projects = projects;
}
});
}
}
}]);
app.directive('languages', ['projectService', '$filter', function(projectService, $filter) {
return {
restrict: 'E',
templateUrl: "directives/languages-directive.html",
scope: {
languagenames: "="
},
controller: function($scope)
{
projectService.getLanguages().then(function(response) {
$scope.languages = $scope.languagenames.map(function (l) {
var matchLangs = $filter('filter')(response.data.languages, { name: l });
if (matchLangs.length) {
return matchLangs[0];
} else {
return { FullName: l };
}
});
});
}
}
}]);
app.controller('PortfolioController', ['$scope', 'projectService', function($scope, projectService) {
$scope.projectlimit = 4;
}]);
app.controller('ProjectsController', ['$scope', 'projectService', function($scope, projectService) {
}]);
How to call the directive:
<projects></projects>
and if you want to limit it, you can add parameter:
<projects limitto="projectlimit"></projects>

AngularJS with UI-Route and Master Detail

I'm trying to get JSON data from my server and display them into my website. I am using Ui-router extension. What I am looking for here is a master-detail setup.
Index.html
<input ng-model="manga.name" ng-change="searchManga()" id="search" type="search" placeholder="Manga İsmi Girin..." required>
<div class="row" ui-view="viewA">
<div class="col s8 offset-s1" ng-controller = "nbgCtrl">
<div class="row">
<div class="col s12 m6 l4" ng-repeat = "manga in mangas">
<div class="row">
<div class="col s5">
<a ui-sref="ui-sref="#/manga/{{manga.id}}"" class="thumbnail">
<img src="/kapaklar/{{manga.kapak}}">
</a>
</div>
<div class="col s7">
<p>{{manga.ad}}</p>
<a href="" class="waves-effect waves-light btn">
</a>
I have above a main page and repeating some thumbnails. Every thumbnail links to its detailed information page. And when clicking a thumbnail it has to carry its own data and load it here. Here's what I've got so far:
JS:
angular.module('nasuh',["ui.router"])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('list', {
url: "/",
controller: "ListCtrl",
templateUrl: "index.html",
}
)
$stateProvider
.state('icerik', {
url: "/icerik/:{{mangaid}}",
controller: "mmgCtrl",
views: {
"viewA": { templateUrl: "icerik.html" },
}
}
)
})
.factory('Mangas', function($http){
var factory = {};
function getData(manganame, callbak) {
var url = '/uzak/remote.php?callback=JSON_CALLBACK';
$http.get(url).success(function(data){
factory = data.results;
callback(data.results);
})
}
return {
list: getData,
find: function(name, callback) {
console.log(name);
var manga = cachedData.filter(function(entry) {
return entry.id == name;
})[0];
callback(manga);
}
};
})
.controller('ListCtrl', function($scope, $http, Mangas) {
$scope.manga = {
name: '' }
$scope.searchManga = function() {
Mangas.list($scope.manga.name, function(mangas) {
$scope.mangas = mangas;
});
}
})
.controller('mmgCtrl', function($scope, $http, $stateParams, Mangas) {
Mangas.find($stateParams.mangaid, function(manga) {
$scope.manga = manga;
});
})
I just doubt that the getData is not a promise in resolve closure you hava returned MY.isimler.then so in mmgCtrl controller first console getData to make sure it's a promise or data

content is loading everytime I refresh the page

I'm developing a simple CRUD application with MEAN stack. So the scenario is a user post a data to the server and it will render the data in real-time. Everything works fine but whenever I refresh the page ,
It will sort of loads all the content, every time it tries to fetch the data. I guess this is a caching problem.
So what I want to achieve is, every time a user refresh the page or go to another link, the content will be there without waiting for split seconds.
Here's the link to test it on, try to refresh the page
https://user-testing2015.herokuapp.com/allStories
and the code
controller.js
// start our angular module and inject our dependecies
angular.module('storyCtrl', ['storyService'])
.controller('StoryController', function(Story, $routeParams, socketio) {
var vm = this;
vm.stories = [];
Story.all()
.success(function(data) {
vm.stories = data;
});
Story.getSingleStory($routeParams.story_id)
.success(function(data) {
vm.storyData = data;
});
vm.createStory = function() {
vm.message = '';
Story.create(vm.storyData)
.success(function(data) {
// clear the form
vm.storyData = {}
vm.message = data.message;
});
};
socketio.on('story', function (data) {
vm.stories.push(data);
});
})
.controller('AllStoryController', function(Story, socketio) {
var vm = this;
Story.allStories()
.success(function(data) {
vm.stories = data;
});
socketio.on('story', function (data) {
vm.stories.push(data);
});
})
service.js
angular.module('storyService', [])
.factory('Story', function($http, $window) {
// get all approach
var storyFactory = {};
var generateReq = function(method, url, data) {
var req = {
method: method,
url: url,
headers: {
'x-access-token': $window.localStorage.getItem('token')
},
cache: false
}
if(method === 'POST') {
req.data = data;
}
return req;
};
storyFactory.all = function() {
return $http(generateReq('GET', '/api/'));
};
storyFactory.create = function(storyData) {
return $http(generateReq('POST', '/api/', storyData));
};
storyFactory.getSingleStory = function(story_id) {
return $http(generateReq('GET', '/api/' + story_id));
};
storyFactory.allStories = function() {
return $http(generateReq('GET', '/api/all_stories'));
};
return storyFactory;
})
.factory('socketio', ['$rootScope', function ($rootScope) {
var socket = io.connect();
return {
on: function (eventName, callback) {
socket.on(eventName, function () {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
},
emit: function (eventName, data, callback) {
socket.emit(eventName, data, function () {
var args = arguments;
$rootScope.$apply(function () {
if (callback) {
callback.apply(socket, args);
}
});
});
}
};
}]);
api.js (both find all object and single object)
apiRouter.get('/all_stories', function(req, res) {
Story.find({} , function(err, stories) {
if(err) {
res.send(err);
return;
}
res.json(stories);
});
});
apiRouter.get('/:story_id', function(req, res) {
Story.findById(req.params.story_id, function(err, story) {
if(err) {
res.send(err);
return;
}
res.json(story);
});
});
For api.js whenever I refresh the page for '/all_stories' or go to a '/:story_id' it will load the data for split seconds.
allStories.html
<div class="row">
<div class="col-md-3">
</div>
<!-- NewsFeed and creating a story -->
<div class="col-md-6">
<div class="row">
</div>
<div class="row">
<div class="panel panel-default widget" >
<div class="panel-heading">
<span class="glyphicon glyphicon-comment"></span>
<h3 class="panel-title">
Recent Stories</h3>
<span class="label label-info">
78</span>
</div>
<div class="panel-body" ng-repeat="each in story.stories | reverse" >
<ul class="list-group">
<li class="list-group-item">
<div class="row">
<div class="col-xs-10 col-md-11">
<div>
<div class="mic-info">
{{ each.createdAt | date:'MMM d, yyyy' }}
</div>
</div>
<div class="comment-text">
<h4>{{ each.content }}</h4>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="col-md-3">
</div>
The loading problem you see is that the data is fetched after the view has been created. You can delay the loading of the view by using the resolve property of the route:
.when('/allStories', {
templateUrl : 'app/views/pages/allStories.html',
controller: 'AllStoryController',
controllerAs: 'story',
resolve: {
stories: function(Story) {
return Story.allStories();
}
}
})
Angular will delay the loading of the view until all resolve properties have been resolved. You then inject the property into the controller:
.controller('AllStoryController', function(socketio, stories) {
var vm = this;
vm.stories = stories.data;
});
I think you should use local storage. suited module - angular-local-storage
The data is kept aslong you or the client user clean the data,
Usage is easily:
bower install angular-local-storage --save
var storyService = angular.module('storyService', ['LocalStorageModule']);
In a controller:
storyService.controller('myCtrl', ['$scope', 'localStorageService',
function($scope, localStorageService) {
localStorageService.set(key, val); //return boolean
localStorageService.get(key); // returl val
}]);
Match this usage to your scenario (for example - put the stories array on and just append updates to it)

Getting undefined in AngularJS

I'm working on building a little app that accepts input from a form (the input being a name) and then goes on to POST the name to a mock webservice using $httpBackend. After the POST I then do a GET also from a mock webservice using $httpBackend that then gets the name/variable that was set with the POST. After getting it from the service a simple greeting is constructed and displayed back at the client.
However, currently when the data gets displayed now back to the client it reads "Hello undefined!" When it should be reading "Hello [whatever name you inputed] !". I used Yeoman to do my app scaffolding so I hope everyone will be able to understand my file and directory structure.
My app.js:
'use strict';
angular
.module('sayHiApp', [
'ngCookies',
'ngMockE2E',
'ngResource',
'ngSanitize',
'ngRoute'
])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/'
});
})
.run(function($httpBackend) {
var name = 'Default Name';
$httpBackend.whenPOST('/name').respond(function(method, url, data) {
//name = angular.fromJson(data);
name = data;
return [200, name, {}];
});
$httpBackend.whenGET('/name').respond(name);
// Tell httpBackend to ignore GET requests to our templates
$httpBackend.whenGET(/\.html$/).passThrough();
});
My main.js:
'use strict';
angular.module('sayHiApp')
.controller('MainCtrl', function ($scope, $http) {
// Accepts form input
$scope.submit = function() {
// POSTS data to webservice
setName($scope.input);
// GET data from webservice
var name = getName();
// Construct greeting
$scope.greeting = 'Hello ' + name + ' !';
};
function setName (dataToPost) {
$http.post('/name', dataToPost).
success(function(data) {
$scope.error = false;
return data;
}).
error(function(data) {
$scope.error = true;
return data;
});
}
// GET name from webservice
function getName () {
$http.get('/name').
success(function(data) {
$scope.error = false;
return data;
}).
error(function(data) {
$scope.error = true;
return data;
});
}
});
My main.html:
<div class="row text-center">
<div class="col-xs-12 col-md-6 col-md-offset-3">
<img src="../images/SayHi.png" class="logo" />
</div>
</div>
<div class="row text-center">
<div class="col-xs-10 col-xs-offset-1 col-md-4 col-md-offset-4">
<form role="form" name="greeting-form" ng-Submit="submit()">
<input type="text" class="form-control input-field" name="name-field" placeholder="Your Name" ng-model="input">
<button type="submit" class="btn btn-default button">Greet Me!</button>
</form>
</div>
</div>
<div class="row text-center">
<div class="col-xs-12 col-md-6 col-md-offset-3">
<p class="greeting">{{greeting}}</p>
</div>
</div>
At the moment your getName() method returns nothing. Also you cant just call getName() and expect the result to be available immediately after the function call since $http.get() runs asynchronously.
You should try something like this:
function getName () {
//return the Promise
return $http.get('/name').success(function(data) {
$scope.error = false;
return data;
}).error(function(data) {
$scope.error = true;
return data;
});
}
$scope.submit = function() {
setName($scope.input);
//wait for the Promise to be resolved and then update the view
getName().then(function(name) {
$scope.greeting = 'Hello ' + name + ' !';
});
};
By the way you should put getName(), setName() into a service.
You can't return a regular variable from an async call because by the time this success block is excuted the function already finished it's iteration.
You need to return a promise object (as a guide line, and preffered do it from a service).
I won't fix your code but I'll share the necessary tool with you - Promises.
Following angular's doc for $q and $http you can build yourself a template for async calls handling.
The template should be something like that:
angular.module('mymodule').factory('MyAsyncService', function($q, http) {
var service = {
getNames: function() {
var params ={};
var deferObject = $q.defer();
params.nameId = 1;
$http.get('/names', params).success(function(data) {
deferObject.resolve(data)
}).error(function(error) {
deferObject.reject(error)
});
return $q.promise;
}
}
});
angular.module('mymodule').controller('MyGettingNameCtrl', ['$scope', 'MyAsyncService', function ($scope, MyAsyncService) {
$scope.getName = function() {
MyAsyncService.getName().then(function(data) {
//do something with name
}, function(error) {
//Error
})
}
}]);

Categories

Resources