I've been working on the CodeSchool AngularJS app, which I've understand so far, but when I began using dependency injections, specifically, $http in order to make an call for my JSON data the app stops working, and I don't know why. Originally with the first line uncommented the app worked as it should using the variable gems declared within the closure, which is exactly the same code now found in products.json. I commented out the first line of the controller, and added the appropriate changes to for dependency injection, but now the app doesn't load at all, and it throws the error found below (also see $http-injection.png).
app.controller('StoreController', [ '$http', function($http) {
//this.products = gems; <-- works like this with data in closure
var store = this;
store.products = [ ]; // no erros on page load
$http.get('/data/products.json').success(function( data ) {
store.products = data;
});
}]);
Error: [ngRepeat:dupes] http://errors.angularjs.org/1.3.0-beta.10/ngRepeat/dupes?p0=product%20in%20storeCtrl.products&p1=string%3A%0D
at Error (native)
at http://angularjs.dev/angular-1.3/angular.min.js:6:457
at http://angularjs.dev/angular-1.3/angular.min.js:204:24
at Object.<anonymous> (http://angularjs.dev/angular-1.3/angular.min.js:108:144)
at Object.applyFunction [as fn] (<anonymous>:778:50)
at g.$digest (http://angularjs.dev/angular-1.3/angular.min.js:109:211)
at g.$delegate.__proto__.$digest (<anonymous>:844:31)
at g.$apply (http://angularjs.dev/angular-1.3/angular.min.js:112:325)
at g.$delegate.__proto__.$apply (<anonymous>:855:30)
at g (http://angularjs.dev/angular-1.3/angular.min.js:73:287) angular.js:10811
(anonymous function) angular.js:10811
(anonymous function) angular.js:7962
g.$digest angular.js:12560
$delegate.__proto__.$digest VM8634:844
g.$apply angular.js:12858
$delegate.__proto__.$apply VM8634:855
g angular.js:7380
x angular.js:8527
y.onreadystatechange
product.json
[
{
name: 'Hexagonal',
price: 250.00,
description: 'The six faces of the hexaonal gem have a habit to excite the eye, and attract good luck.',
canPurchase: true,
soldOut: false,
images: [ ],
reviews: [
{
stars: 5,
body: "I love this product!",
author: "mtpultz#gmail.com"
},
{
stars: 1,
body: "This product sucks!",
author: "mtpultz#hater.com"
}
]
},
{
name: 'Dodecahedron',
price: 1015.25,
description: 'Some gems have hidden qualities beyond their luster, beyond their shine... Dodeca is one of those gems.',
canPurchase: true,
soldOut: false,
images: [
"img/gem-06.gif",
"img/gem-02.gif",
"img/gem-01.gif"
],
reviews: [
{
stars: 3,
body: "I think this gem was just OK, could honestly use more shine, IMO.",
author: "mtpultz#hotmail.com"
},
{
stars: 4,
body: "Any gem with 12 faces is for me!",
author: "mtpultz#casensitive.ca"
}
]
},
{
name: 'Pentagonal Gem',
price: 5.95,
description: 'Origin of the Pentagonal Gem is unknown, hence its low value. It has a very high shine and 12 sides however.',
canPurchase: true,
soldOut: false,
images: [
"img/gem-02.gif",
"img/gem-06.gif",
"img/gem-01.gif"
],
reviews: [
{
stars: 4,
body: "The mystery of the Pentagonal Gem makes it sooo fascinating!",
author: "mtpultz#peanutbutter.com"
},
{
stars: 5,
body: "I can't get enough of the five faces of the Pentagonal Gem!",
author: "mtpultz#ketchup.ca"
}
]
}
];
Originally I was going to try and figure out how to use $log as well, and when I had $log injected it appears as if the json is received (see $http-and-$log-injection.png attached) based on the chrome batarang plugin's output, but the app still doesn't work either way, only the JSON appears on right side of batarang output.
app.controller('StoreController', [ '$http', '$log', function($http, $log) {
//this.products = gems;
var store = this;
store.products = [ ]; // no erros on page load
$http.get('/data/products.json').success(function( data ) {
store.products = data;
});
}]);
You shouldn't use the minified version of Angular while developing. You'll get better error messages when using the non-minified version. But even when you're using the minified version you can get a pretty good idea of what the problem is by visiting the url mentioned first in the exception: http://errors.angularjs.org/1.3.0-beta.10/ngRepeat/dupes?p0=product%20in%20storeCtrl.products&p1=string%3A%0D
It seems like you have duplicates in products.json. Without seeing the whole contents of products.json or any of your markup that would be my best guess.
--
Update: It seems like data is a string and not an array. This is probably because the response body from the server is not properly formatted JSON. Instead of traversing objects in an array, ng-repeat traverses characters in a string and throws an error on the second tab character (encoded as %0D) it detects. I've created a plnkr with properly and a bad response as an example: http://plnkr.co/edit/XbPuXkykzv36NyH3sSeu?p=preview
You should use $scope:
$scope.store = {};
$scope.store.products = [ ]; // no erros on page load
$http.get('/data/products.json').success(function( data ) {
$scope.store.products = data;
});
ngRepeat:dupes error occurs if there are duplicate keys(values in your array/json) in an ng-repeat expression, this is because AngularJS uses keys to associate DOM node with ng-repeated items. The requested data products.json may have fields that contain the same value, to solve this, you can append a track by $index expression in your ng-repeat so that the association of DOM node items will be keyed by the index of the your array/json instead of the value of each item.
E.G.
<div ng-repeat="product in Store.products track by $index"></div>
Related
So I a using the node paypal-rest-sdk module and I'm trying to create a billing plan. Using the documentation here I made this JSON:
const billingPlanAttributes = {
name: 'Subscription',
description: 'Monthly subscription plan',
type: 'INFINITE',
payment_definitions: [{
name: 'Regular monthly infinite payments',
type: 'REGULAR',
frequency_interval: '1',
frequency: 'MONTH',
cycles: '0',
amount: {
currency: 'USD',
amount: '4.99',
},
}],
merchant_preferences: {
cancel_url: 'http://localhost:3000/subscribe/cancel',
return_url: 'http://localhost:3000/subscribe/return',
auto_bill_amount: 'YES',
},
};
But when using the paypal.billingPlan.create(... function I get the error 'MALFORMED_REQUEST', 'Incoming JSON request does not map to API request'. So I guess my JSON is not in the correct format or I'm missing something that is need.
The documentation has a charge_models key but it does not mention that it is required unlike other keys.
If you can point me in the right direction that would be great.
Edit: changed the return url and cancel url to include the full domain but still same error.
There could be more to this, but I noticed one thing wrong with your JSON. Remove commas for items last in a list. After 'amount' and 'merchant_preferences'. JSON is picky.
late answer, I know, but ran in exactly the same issue than you.
In the create function of the billing plan
public function create($apiContext = null, $restCall = null)
{
$payLoad = $this->toJSON();
$json = self::executeCall(
"/v1/payments/billing-plans/",
"POST",
$payLoad,
null,
$apiContext,
$restCall
);
$this->fromJson($json);
return $this;
}
I found out, that the toJSON method always returned false. Why the hell!?!
I did the same as you did and copied the complete sample code into my code. Then it worked as expected. Now I checked, what the difference was in to my code.
I realized, that I used an umlauts (ä,ü,ö) in the name and description of the billing plan. I changed the umlauts to
'ä' => 'ae',
'ö' => 'oe'
'ü' => 'ue'
Then it worked fine! Maybe someone else is running in this issue, too.
I've got an angular controller containing a json object
app.controller("buildControl", function($scope){
$scope.buildData = [
{
'title':'Workspace',
'options': [{
'title': 'Studio'
},{
'title': 'Garage'
},{
'title': 'Blank'
}]
},{
'title':'Frame',
'options': [{
'title': 'Studio'
},{
'title': 'Garage'
},{
'title': 'Blank'
}]
}]
});
I'm using this data to iterate the object's arrays using ng-repeat (plus I have other functions in my controller that use the data).
Everything runs fine until I moved the json out into it's own file and used $http to include it.
app.controller("buildControl",function($http, $scope){
$http.get("json/buildData.js")
.success(function(response){
$scope.buildData = response.data;
}).error(function(error){
console.log(error);
});
});
The only errors I get in my console are from all my other functions breaking without the data they need to run, plus an 'undefined' from my console log. So I know that it's going to '.error'.
I figured maybe I had the filepath wrong, have tried changing prefixing it with '../' to go up a directory out of my controllers. No luck. If I put the json in the same folder and just write;
.get("buildData.js")
I get this as the error
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /buildData.js was not found on this server.</p>
</body></html>
But then I sort out the filepath and it goes back to undefined. So I don't think this is the problem.
(I'm doing this using MAMP and having no HTTP errors associated with trying to get files locally).
Any help?
Not sure if you need to use $http here, why not include your data from a service, something like:
angular
.module('MyApp')
.service('buildData', buildData);
function buildData() {
return [{
'title':'Workspace',
'options': [{
'title': 'Studio'
},{
'title': 'Garage'
},{
'title': 'Blank'
}]
...
}]
};
Your controller would look something like this:
.controller('buildControl', buildControl);
buildControl.$inject = ['$scope', 'buildData'];
function buildControl($scope, buildData) {
$scope.buildData = buildData;
...
}
I have been racking my brain and google all morning trying to figure this out but I have come to the conclusion that I need to ask the experts! I am trying to do nested attributes with Sinatra and Angular, don't worry about the Sinatra side of things I am just trying to get the data to the server side in the correct manner at the moment. Please see the code below for an explanation of
My Input:
<input type="text" placeholder="{{item.placeholder}}" ng-model="question.possible_answer_attributes[$index][title]" class="form-control" />
My model object:
$scope.question = new Question({
poll_id: parseInt($routeParams.id),
title: '',
kind: 'open',
possible_answer_attributes: [] // I believe the issue may lie here
});
My factory:
.factory('Question', function($resource) {
return $resource('/api/questions/:id', { id: '#id' }, {
'update' : { method: 'PUT' },
'get_by_poll' : { method: 'GET', url: '/api/questions_by_poll/:id', isArray: true }
});
})
My object at time of running save function:
{"poll_id"=>1, "title"=>"123123", "kind"=>"multiple", "possible_answer_attributes"=>[{"undefined"=>"412312"}, {"undefined"=>"1234124"}, {"undefined"=>"234235234"}]}
I do not understand why my "possible_answer_attributes" keys are coming through as "undefined". It may be something very simple that I have missed, but any feedback would be great!
Thanks in advance!
In order to address the title property, you would need to use a string to index into the object:
ng-model="question.possible_answer_attributes[$index]['title']"
This should hold as long as possible_answer_attributes array looks like:
[{ title: 'my title' }]
So, I am learning Angular JS from codeschool course "Shaping up with angular js". The guy on the videos says, that wrapping code in (function(){}) is a good habbit.
BUT, when I do that Im getting an error[$injector:modulerr]`. Without this self-called function syntax everything works fine. And it bothers me, why they tell to do this way, and why does it cause error?
Seems that you are missing the (); self executing braces at the end of your anonymous function:
(function(){
// all your code
})();
//^^^--------------add this (); at the closing.
Usually the format should look like this:
angular.module("gemStore", []).controller("StoreController", function () {
var gems = [
{ name: "Dodecahedron", price: 2, desc: "some description", canPurchase: true },
{ name: "Pentagonal gem", price: 5.95, desc: "...", canPurchase: true }
];
this.products = gems;
})
I've taken over a slightly broken ember project, but I can't get even the most basic model to work. I've commented out all of the code of the former project, and have basically just this:
App = Ember.Application.create();
App.ApplicationAdapter = DS.FixtureAdapter.extend
App.Admin = DS.Model.extend(
userName: DS.attr("string")
roles: DS.attr("string")
)
App.Admin.FIXTURES = [
{
userName: 'Tester One'
roles: 'six-sided die'
}
{
userName: 'Tester Two'
roles: 'four-sided die'
}
]
App.Router.map ->
#route 'about', { path: '/about' }
#resource 'admins', { path: '/admins' }
App.AdminsRoute = Ember.Route.extend
model: ->
return #store.find('admin')
It's built inside of a Rails 4.0.1 app (running 0.14.1 of ember-rails and 1.3.2 of ember-source). When I go to the root page, I see the proper ember template. When I click on the link for about, I get routed to the about template. But when I click on admins or go to /admins, instead of having it render the admins template (which is just some static text), I get this error in my js console:
Error while loading route: TypeError: Object function () {
var Class = makeCtor(), proto;
Class.ClassMixin = Mixin.create(this.ClassMixin);
Class.PrototypeMixin = Mixin.create(this.PrototypeMixin);
Class.ClassMixin.ownerConstructor = Class;
Class.PrototypeMixin.o...<omitted>... } has no method 'create'
followed by a bunch of backtraces inside the ember code. I don't call create anywhere, and it was giving a similar error for the other models in the app that I've (since) commented out. I've tried to build this following the ember guide as something that would work for sure.
The Ember inspector sees an admins route named AdminsRoute using the AdminsController and admins template at /admins.
Simply put, I don't know how to debug this any further.
I've tried several versions of ember/-data, but currently I'm using 1.4.0-beta.6 and 1.0.0-beta.6 and getting this error still.
Thanks!
This is a common mistake when using coffeescript with ember, you have to update
App.ApplicationAdapter = DS.FixtureAdapter.extend
to
App.ApplicationAdapter = DS.FixtureAdapter.extend()
Could it be the missing comma?
App.Admin.FIXTURES = [
{
userName: 'Tester One'
roles: 'six-sided die'
}
{
userName: 'Tester Two'
roles: 'four-sided die'
}
]
to
App.Admin.FIXTURES = [
{
userName: 'Tester One'
roles: 'six-sided die'
},
{
userName: 'Tester Two'
roles: 'four-sided die'
}
]
Try giving the models in your fixtures a unique id
I suspected something might be up with the upgrade process, and it was an imperfect implementation of the store.
store.coffee had read simply:
App.ApplicationAdapter = DS.FixtureAdapter.extend
I changed that to:
App.Store = DS.Store.extend
adapter:DS.FixtureAdapter
And it worked fine (though I did have to add ids, as #chopper noted). Seeing as we'll be using an api for the store, I'll stick to this variant, though #marcio-junior's suggestion also worked! Thanks!