I want to give a post request using my API. The JSON is like this:
{
"_id": "56b8e96xxxxxxxxxx7cd",
"name": "abc",
"conditions": [
{
"name": "Condition 1"
},
{
"name": "Condition 2"
}
],
"id": 10
}
The following is the angular code:
app.factory('Cohort', function($resource) {
return $resource('http://API URL:id')
});
I am using the following angular function to give the post request:
$scope.createCohort= function (){
var arr=["condition 1","condition 2"];
var cohort=new Cohort();
cohort.name=$scope.CohortName;
cohort.id=$scope.CohortId;
for(var i=0;i<length_of_arr;i++)
{
cohort.conditions[i].name=arr[i] // This line gives me error.
}
Cohort.save(cohort,function(){
});
};
The error is
Cannot read property '0' of undefined
How can I give the post request to it ?
Since you don't precise where you declare you var arr=[..]. I presume you have declare it inside a function and not in your controller which make it invisble to the createCohort function.
Either declare a var arr=[] in your controller (not in a function define in it) and remove the var on the place you set the value (so you don't mask it). Or use $scope.arr = [...];
Note that if you never use arr in your view template it's better to not store it in the $scope because angular watch evrery change of all fields in the $scope.
EDIT :
here is the problem: before the for loop add :
cohort.conditions = [];
and in the for loop do :
cohort.conditions.push({name:arr[i]});
Related
I have a $getJSON() that i want to pass a var through how ever i always get undefined in console log.
I have done this before i just cant seem to figure out why this isnt working.
Any help would be appreciated.
here is my example
{
"harry": {
"example": "test",
"example1": "test",
}
"james": {
"example": "test",
"example1": "test",
}
"ben": {
"example": "test",
"example1": "test",
}
}
var usersidno = $("#hiddenid").html();
$.getJSON(
"http://localhost/example/file.json",
function(json) {
console.log(json.usersidno);
});
<div id="hiddenid">harry</div>
When you want to access an object's (JSON) property dynamically (using a variable or expression), you should use square bracket notation.
[your expression or variable inside square brackets]. i.e, json[useridno]
var usersidno = $("#hiddenid").html();
$.getJSON(
"http://localhost/example/file.json",
function(json) {
console.log(json[usersidno]); // try to use square brackets
});
This is a working example of ,your issue I have used an api ,that gives back a json ,You can use [] annotatiton to access object properties.
$(document).ready(function(){
var user = $("#hiddenid").html()
console.log(typeof user)
$.getJSON(
"https://jsonplaceholder.typicode.com/todos/1",
function(json) {
let js=JSON.parse(JSON.stringify(json))
console.log(js[user]);
console.log(js.user);//undefined
console.log(js)
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="hiddenid">userId</div>
Explanation:
var userid = 'userId';
console.log(x.userid); // it looks for x.userid, which throws undefined,if it does'nt exists
console.log(x[userid]); // looks for x['userId'] which it will find
Have a look at mdn docs
here is a simple response json:
{
"blog": {
"title": "Blog"
"paragraphs": [{
"title": "paragraph1",
"content": "content1"
}, {
"title": "paragraph2",
"content": "content2"
}, {
"title": "paragraph3",
"content": "content3"
}
],
"selectList": ["food", "play", "mood"]
}
}
If something wrong with server, paragraphs property is undefined, how I avoid to make error in the client side? Even I still could get other datas successfully, like blog.title, blog.selectList...etc
if I don't want to use :
if (response.blog && response.blog.paragraphs && response.blog.paragraphs....) {
//do something
}
Because if there are many level in JSON object, it is not efficient way. Is anyone have smart and efficient way?
UPDATE
#MatthewHerbst said:just check the lowest property.
if I just check the lowest property(response.blog.paragraphs), that will make javascript error, crush my site. because the browser found response.blog is undefined. In the real case, if response.blog is undefined, I will get response.error property, then if(response.blog.paragraphs) will encounter error, because response object doesn't defined blog property in javascript. how I just check the lowest property?
You could use lodash for this. E.g.
let paragraphs = _.get(response, 'blog.paragraphs', null);
if (!paragraphs) {
// Couldn't get from response.
} else {
// Do something with response.blog.paragraphs.
}
You can do something like this-
var blogs = response.blogs;
if(blogs){
//do something
var paraData = blogs.paragraphs;
if (paraData){
// do some more fun
}
}
OR
You can do something like this-
var arrKeys = Object.keys(blogs),
newBlogArr = [] // to get the filtered result;
(function(){
for(i=0;i<arrKeys.length;i++){
// to get the filtered defined objects only
if(blogs[arrKeys[i]] !== null || blogs[arrKeys[i]] !== undefined){
//Now simply push that array in newBlogArr;
newBlogArr.push(blogs[arrKeys[i]]);
}
}
return newBlogArr;
})();
I have some complex question.
My first JSON url has this properties, ID, Name and Parameter. Then when I call the JSON, I want to go to retrieve another JSON URL based on the ID to get the child ID.
Then I want to output as Child ID, Parent Name and Parent Parameter.
Here is the jsFiddle http://jsfiddle.net/c3L7gr4w/1/
And here is the model url 1
[
{
"ParemeterValues": "Actual,2011,SYS.LoadCompanies,y,y",
"ID": "1771cdf7-7a73-49e4-8538-0d0cad965226",
"Name": "EXEC.Data.PLandBS.FromFMISMultipleCompanies",
},
{
"ParemeterValues": "Actual,2012",
"ID": "19439ce4-240c-4f2a-98ee-47cb1708b339",
"Name": "Data.BS.BringForwardOpeningBalances",
}
]
and the model url2
{
"ID": "1771cdf7-7a73-49e4-8538-0d0cad965226",
"Name": "EXEC.Data.PLandBS.FromFMISMultipleCompanies",
"TM1.ChoreProcessesProcess":
[
{
"Name": "EXEC.Data.PLandBS.FromFMISMultipleCompanies",
"ID": "dd1acc0b-51ff-4844-b6c4-c67640b326c4",
}
]
}
I think you need to adjust your dataMappingOptions.key so that KO can return a different key when you load your child model in on top of your original.
I have a working fiddle here, I think - http://jsfiddle.net/sifriday/c3L7gr4w/4/
dataMappingOptions now looks like:
var dataMappingOptions = {
key: function(data) {
var ChildID = "";
if (data["TM1.ChoreProcessesProcess"] != undefined)
ChildID = data["TM1.ChoreProcessesProcess"][0].ID
return data.ID + ChildID;
},
create: function(options) {
return new Person(options.data);
}
};
The problem with this is that when you load your updatedData KO will now use the mapping to destroy your original people and create new ones. However, updatedData is missing the ParemeterValue, so you need to merge this in from your original JSON. This will be OK even when you are using Ajax, because you can save the original JSON in a variable somewhere:
loadUpdatedData: function() {
// You need to merge in paremeterValues from your orig JSON
updatedData[0].ParemeterValues = data[0].ParemeterValues;
// Now good to go...
ko.mapping.fromJS(updatedData, dataMappingOptions, viewModel.people);
}
(I've also done it so that ChildID is appended as an extra property, but you should be able to see from this how to make it replace the original ID in both the People view-model and in the dataMappingOptions.key)
I have a rather simple question. I have a simple controller and its $scope.coords = []; renders JSON in HTML:
[24.43359375, 54.6611237221]
[25.2905273438, 54.6738309659]
[25.3344726562, 54.6102549816]
[25.2685546875, 54.6801830971]
[25.2960205078, 54.6611237221]
How can I render that JSON not in html, but in my controller itself ? The code looks like that. Please see the comment in code:
propertyModule.controller('propertyController', ['$scope', 'Property', function ($scope, Property) {
// Query returns an array of objects, MyModel.objects.all() by default
$scope.properties = Property.query();
// Getting a single object
$scope.property = Property.get({pk: 1});
$scope.coords = [];
$scope.properties = Property.query({}, function(data){
console.log(data);
angular.forEach(data , function(value){
$scope.coords.push(value.coordinates);
});
});
$scope.positions = //$Resource('realestate.property').items();
[
[54.6833, 25.2833], [54.67833, 25.3033] // those coordinates are hardcoded now, I want them to be rendered here by $scope.coords
];
}]);
First off, you're showing us a bunch of arrays, not a JSON document. But since your code seems to be working, I'll assume you do have a valid JSON to work with.
You need to consider the fact that you are making an asynchronous request here :
$scope.properties = Property.query({}, function(data) {
console.log(data);
angular.forEach(data , function(value){
$scope.coords.push(value.coordinates);
});
});
This means you won't be able to fetch data from $scope.coords before anything has arrived.
There are several ways to solve that :
You could simply fetch data while you're still in the loop :
angular.forEach(data , function(value) {
$scope.coords.push(value.coordinates);
if('your condition') {
$scope.positions.push(value.coordinates);
}
});
You could use a promise, see the angular doc.
Or you could watch over $scope.coords with $scope.$watch.
I am badly stuck with this problem of passing data from one controller to other in angularJS. Before my code was: whenever I click on templateController's div, it would trigger setTemplate with the help of ng-click... Now my objective was to send templateController's selected data to ReplyController...
After reading forum posts here, i decided to create a service called 'selectionService', so that i can transmit data between 2 controllers...
//Defined Service
proApp.service('selectionService', function() {
var selected_template;
addTemplate = function(newObj) {
selected_template = newObj;
};
getTemplate = function(){
return selected_template;
};
});
//Controller 1... where templates are selected
proApp.controller('TemplateController',function($scope, selectionService)
{
$scope.templates = [
{template_name:"Template 1", template_text:"We apologize for the interruption."} ,
{template_name:"Template 2", template_text:"Thank you for contacting us."} ,
} ,
];
// on ng-click
$scope.setTemplate = function(tmp)
{
selectionService.addTemplate(tmp);
}
});
// Controller 2 ... supposed to catch the selected template.
proApp.controller('ReplyController', function($scope, selectionService)
{
$scope.template = selectionService.getTemplate();
});
So whenever i run this code, i started getting this error
Object [object Object] has no method addTemplate...
Again I tweeked the code where they were suggesting to use Squarebrackets and put $scope , servicename and then write function with same parameters.. I don't understand why I should do this? Event after doing some changes like
[ '$scope' , 'service' , function($scope, service){}] ,
I am still not able to figure out the solution to pass data from one controller to other using service.
Could you help? What am I missing? I am very new to angularJS way of doing stuff.
I think it's actually quite simple. You just need to add your methods to the service by using this.. Currently they are declared on window. Change your service declaration to use this...
proApp.service('selectionService', function() {
var selected_template;
this.addTemplate = function(newObj) {
selected_template = newObj;
};
this.getTemplate = function(){
return selected_template;
};
});
As for using the array notation for dependencies, it's a good practice but it's not required. It'll save you from headaches if you ever run your code through a minifier.