Trouble including JSON in angular controller - javascript

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;
...
}

Related

AngularJs crashes when trying to access data in directive

So I'm new to Angular and trying to do an app. My server is very basic and written in go. This is my angular code-
(function() {
var app = angular.module('dashboard', []);
app.controller("JobsController", function() {
this.currentJob = 0;
this.jobs = jobs;
this.setCurrentJob = function(index) {
this.currentJob = index;
};
});
var jobs = [
{
'id': 1,
'requester': 'Prakash Sanker',
'description': 'I want you to give me the entire world'
},
{
'id': 2,
'requester': 'MJ Watson',
'description': 'Please give me Spiderman, preferably upside down...but Im not fussy'
},
{ 'id': 3,
'requester': 'Josh Lyman',
'description': 'Matthew Santos as president...or Jed Bartlet..but please not anyone Republican'
},
{
'id': 4,
'requester': 'Barry Allen',
'description': 'A frictionless suit that wont burst into flames when I run at a zillion miles an hour...its for a friend'
},
{
'id': 5,
'requeter': 'A. Bambaata',
'description': 'Boombox, prime condition, from the 80s. Go back in time if you have to'
}
];
})();
This is my index.html -
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script type="text/javascript" src="/dashboard.js"></script>
<body>
<div class="dashboard">
<div ng-controller="JobsController as jobsCtrl">
<div class="jobs">
{{jobsCtrl.jobs[0]}}
</div>
</div>
</div>
</body>
This causes this error on my server
2015/07/29 12:18:02 http: panic serving [::1]:56857: runtime error: invalid memory address or nil pointer dereference
goroutine 18 [running]:
net/http.funcĀ·009()
/usr/local/go/src/pkg/net/http/server.go:1093 +0x9e
runtime.panic(0x20ed40, 0x4efaed)
/usr/local/go/src/pkg/runtime/panic.c:248 +0xda
html/template.(*Template).escape(0x0, 0x0, 0x0)
/usr/local/go/src/pkg/html/template/template.go:52 +0x30
Why is this happening?
You cannot use angular's default start {{ and end }} brackets in a go template because the go server interprets your angular as go template arguments and pipelines.
"Arguments" and "pipelines" are evaluations of data
To solve this you can make use of angular's $interpolate in your config to change the delimiters that define angular code:
var app = angular.module('dashboard', []);
app.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('[{');
$interpolateProvider.endSymbol('}]');
});
Alternatively if your pages are static you can just use Go's built in file server to not cause confusion with templates:
http://golang.org/pkg/net/http/#example_FileServer

Nested attributes with Angular.js

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' }]

Ember.js , HighCharts - accessing JSON data from controller

I need to access JSON data from model, i used "this.model" in controller. From what i see in console log "this.model" is returning array of data arrays.
App.CardsRoute = Ember.Route.extend({
model: function() {
return Ember.$.getJSON('/cards');
}
});
This is what is server on path /cards returning :
[[1317888000000,372.5101],[1317888060000,372.4]]
I want to use that data in my ember HighStock (from HighCharts) implementation. It's drawing chart with this manually entered data:
App.CardsController = Ember.ArrayController.extend({
series: [{
name : 'test',
type: 'area',
data :[[1317888000000,372.5101],[1317888060000,372.4]],
...
But not drawing with this:
App.CardsController = Ember.ArrayController.extend({
series: [{
name : 'test',
type: 'area',
data : this.model,
...
From what i see in console, this.model is returning not only array with arrays of data but other ember specific objects too, is that the problem? if yes then how to access only JSON returned data so i can use it in controller?
You can directly format the data in your router itself, after the promise is successful.
When the controller is initialized, this method also will run once and will intialise.
To setup the data from the controller itself, format the data after the json promise is successful.
Ex:
App.CardsRoute = Ember.Route.extend({
model: function() {
return Ember.$.getJSON('/cards');
}.then(function(data){
return [{
name : 'test',
type: 'area',
data : data,
...
}]
});
After this in controller do this
The code is pasted in the jsbin http://jsbin.com/vekacayirugu/16/edit
This kind of formatting will work for you.
reference: http://emberjs.com/guides/object-model/computed-properties-and-aggregate-data/

$http dependency injection throwing error

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>

How to add a new object to an array nested inside an object?

I'm trying to get a handle on using $resource in angularjs and I keep referencing this answer AngularJS $resource RESTful example for good examples. Fetching a record and creating a record work fine, but now i'm trying to add a "section" to an existing mongo record but can't figure it out.
documents collection
{
_id: 'theid',
name: 'My name",
sections: [
{
title: 'First title'
},
{
title: 'Second title'
}
]
}
angular controller snippet
var document = documentService.get({_id: 'theid'});
// TRYING TO ADD $scope.section TO THE SECTIONS ARRAY IN THE VARIABLE document.
//document.sections.push($scope.section); <-- This does NOT work
//document.new_section($scope.section); <-- could do this and then parse it out and insert it in my backend code, but this solution seems hacky and terrible to me.
document.$save(function(section) {
//$scope.document.push(section);
});
documentService
return $resource(SETTINGS.base + '/documents/:id', { id: '#id' },
{
update: { method: 'PUT' }
});
From the link i posted above, If I was just updating the name field, I could just do something like this:
var document = documentService.get({_id: 'theid'});
document.name = "My new name";
document.$save(function(section) {
//$scope.document.push(section);
});
I'm just trying to add an object to a nested array of objects.
Try this:
documentService.get({_id: 'theid'}, function(document) {
document.sections.push($scope.section);
document.$save();
});

Categories

Resources