AngularJS service access variable defined in service - angularjs

I have a Angular utility server and in that I have one method which I am using for searching some values in a JSON as below.
angular.module('myAppModule')
.service('myService', ['$rootScope', function($rootScope)
{
this.myTestJson = '[{"id":1,"somthing":"somthing"},{"id":2,"somthing":"somthing"}]';
this.getJsonObj = function(id)
{
if(id == null || id == undefined || id == "")
return null;
// Units Convert to JSON
var jsonObj = JSON.parse(JSON.stringify(this.myTestJson)); // How can I avoid this doing every time ?
console.log("getJsonObj: jsonObj.length: "+jsonObj.length); //--> Printed invalid number, length of the string
for(var index=0;index < jsonObj.length;index++)
{
if( id == jsonObj[index].id )
return jsonObj[index];
}
return null;
};
}]);
Problem is I get JSON array length as invalid, and because of that I am not able to loop the array.
How can I access this JSON variable which is defined in the same service.

this.myTestJson = '[{"id":1,"somthing":"somthing"},{"id":2,"somthing":"somthing"}]';
So, myTestJson is a String containing a JSON payload.
var jsonObj = JSON.parse(JSON.stringify(this.myTestJson));
And here, you're serializing this JSON string into JSON, only to reparse it right after. Which doesn't make any sense: you'll end up with the exact same string as the original one. Just like, if you transofmr an integer to a String, and then parse that String into an integer, you'll end up with the original integer.
To parse the original JSON and thus transform it to a JavaScript array, all you need is
var array = JSON.parse(this.myTestJson);
But even this is completely unnecessary, since you could just use a JavaScript array from the start, instead of parsing a JSON string:
var array = [
{
id: 1,
somthing:"somthing"
},
{
id: 2,
somthing: "somthing"
}
];

Related

Unable to access first data item in JSON Array

I'm having trouble pulling a piece of data from a JSON array. I believe I've tried every answer from similar posts here but I'm missing something. I've imported the org.JSON library. Here is my JSON text:
{
"symbol":"AAPL",
"earnings":[
{
"actualEPS":2.34,
"consensusEPS":2.17,
"estimatedEPS":2.17,
"announceTime":"AMC",
"numberOfEstimates":10,
"EPSSurpriseDollar":0.17,
"EPSReportDate":"2018-07-31",
"fiscalPeriod":"Q3 2018",
"fiscalEndDate":"2018-06-30",
"yearAgo":1.67,
"yearAgoChangePercent":0.40119760479041916,
"estimatedChangePercent":0.29 940119760479045,
"symbolId":11
},
{
"actualEPS":2.73,
"consensusEPS":2.69,
...
...
}
]
I'm trying to read the first instance of "actualEPS", there are a total of four in the array. My code currently looks like this:
String jsonIn = sb.toString();
JSONArray earningsArray = new JSONArray(jsonIn);
double eps = 0;
for(int i = 0; i < earningsArray.length(); i++) {
JSONObject jObject = earningsArray.getJSONObject(i);
eps = jObject.getDouble("actualEPS");
} // end for loop
System.out.println("This is the first instance of EPS: " + eps);
The StringBuilder (sb) in the first line is my JSON and prints out correctly in the console just ahead of this block.
The stack trace shows the error in this line:
JSONArray earningsArray = new JSONArray(jsonIn);
The error I'm getting is
"A JSONArray text must start with '[' at 1 [character 2 line 1]"
I've never used JSON prior to now and am not sure what my error is exactly. I tried shortening the String going into the array to begin with just the array opening bracket but that didn't work either. I feel like I'm missing something simple. Where have I gone wrong?
You need to understand there are two types of datastructure in a JSON.
first is Object which always starts with '{' and ends with '}'
second is Array which always starts with '[' and ends with ']'
JsonArray is nothing but an array of JsonObject means a json array will always look like
"jsonarray":[
{
//json object
},
{
// json object
}
]
hope now you understand how json works
now come to your json
{ // jsonObjectParent Starts
"symbol":"AAPL",
"earnings":[ // jsonArray Starts
{ //jsonObject1 Starts
"actualEPS":2.34,
"consensusEPS":2.17,
"estimatedEPS":2.17,
"announceTime":"AMC",
"numberOfEstimates":10,
"EPSSurpriseDollar":0.17,
"EPSReportDate":"2018-07-31",
"fiscalPeriod":"Q3 2018",
"fiscalEndDate":"2018-06-30",
"yearAgo":1.67,
"yearAgoChangePercent":0.40119760479041916,
"estimatedChangePercent":0.29 940119760479045,
"symbolId":11
}, // jsonOject1 Ends
{ //jsonObject2
"actualEPS":2.73,
"consensusEPS":2.69,
...
...
}
] //jsonArray Ends
} //jsonObjectParent Ends
So here if you want to parse this json you have to first parse it in a jsonObject as you seen above
JsonObject jsonObjectParent = new JsonObject(jsonIn);
// here jsonobject contains json array so etract it like this
JsonArray jsonArray = jsonObjectParent.getJsonArray("earnings");
//now you can access the values here
JsonObject jsonObject1 = jsonArray.getJsonObject(0); // here 0 means first jsonObject in array if you want all you can make a loop here
string actualEps = jsonObject1.getDouble("actualEPS");
Hope now you understands the concept of how JSON Works
please let me know is this solution worked
Do this :
JSONObject json = new JSONObject(response);
JSONArray data = json.optJSONArray("earnings");
for (int i = 0; i < data.length(); i++) {
JSONObject jsonObject1 = data.getJSONObject(i);
Double actualEPS = jsonObject1.getDouble("actualEPS");
Double consensusEPS = jsonObject1.getDouble("consensusEPS");
Double estimatedEPS= jsonObject1.getDouble("estimatedEPS");
String announceTime = jsonObject1.getString("announceTime");
int numberOfEstimates = jsonObject1.getInt("numberOfEstimates");
Double EPSSurpriseDollar= jsonObject1.getDouble("EPSSurpriseDollar");
String EPSReportDate= jsonObject1.getString("EPSReportDate");
String fiscalPeriod= jsonObject1.getString("fiscalPeriod");
String fiscalEndDate= jsonObject1.getString("fiscalEndDate");
Double yearAgo= jsonObject1.getDouble("yearAgo");
Double yearAgoChangePercent= jsonObject1.getDouble("yearAgoChangePercent");
Double estimatedChangePercent = jsonObject1.getDouble("estimatedChangePercent");
int symbolId = jsonObject1.getInt("symbolId");
}
#Driver8, the JSON earninsArray is a single JSON object and not an array of JSON objects. Your basic idea here is alright everywhere excpet for just that line. Instead of instantiating a JSON array, instantiate a JSON OBJECT.
Should be something like this:
String jsonIn = sb.toString();
JSONObject earningsObject = new JSONObject(jsonIn);
JSONArray earningsArray = earningsObject.getJSONArray("earnings");
double eps = new double(earningsArray.length());
for (int i = 0; i < earningsArray.length(); i++) {
JSONObject j1 = earningsArray.getJSONObject(i);
eps[i] = j1.getDouble("actualEPS");
}
All the values of actualEPS will be stored as per their order in the array declared to store the EPS values.
Hope this helps.

angular.js:14195 Error: [$resource:badmember] Dotted member path "#" is invalid

I'm using angular.resource js
There I'm trying to access get service which has query param triggered from a form search.
If user search with only "#" in input field, it goes as query param which starts with "#" character then getting above exception
Thanks in advance.
Because of below code in angular.resource js
// Helper functions and regex to lookup a dotted path on an object
// stopping at undefined/null. The path must be composed of ASCII
// identifiers (just like $parse)
var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$#][0-9a-zA-Z_$#]*)+$/;
function isValidDottedPath(path) {
return (path != null && path !== '' && path !== 'hasOwnProperty' &&
MEMBER_NAME_REGEX.test('.' + path));
}
function lookupDottedPath(obj, path) {
if (!isValidDottedPath(path)) {
throw $resourceMinErr('badmember', 'Dotted member path "#{0}" is invalid.', path);
}
var keys = path.split('.');
for (var i = 0, ii = keys.length; i < ii && angular.isDefined(obj); i++) {
var key = keys[i];
obj = (obj !== null) ? obj[key] : undefined;
}
return obj;
}
If you really want ot make this as your url params. Try escape the # char as this has special meaning in $resource library
Normally it happens when we have only # as the value, where it searches for the value of string after "#" in the request body.
As it is a get method, where angular resource ignores it. Very weird behavior.
AngularJs doc: https://code.angularjs.org/1.5.11/docs/api/ngResource/service/$resource
If the parameter value is prefixed with #, then the value for that parameter will be extracted from the corresponding property on the data object (provided when calling a "non-GET" action method). For example, if the defaultParam object is {someParam: '#someProp'} then the value of someParam will be data.someProp. Note that the parameter will be ignored, when calling a "GET" action method (i.e. an action method that does not accept a request body)
So before calling any method in resource try escape the # symbol:
paramValue = paramValue.replace(/#/gi, '\\#');
And again you can remove the scape before api call happens in request method of interceptor service for $httpProvider.
configParams = configParams.replace(/\\#/gi, '#');
Let me know if need any more help.
Thanks

Detection of Index in Angular: indexOf() does not work properly because of $$hasKeys?

Following Situation:
role: { roleid=3, name="admin"}
availableRoles:
[
{ roleid=3, name="admin", $$hashKey="object:222"},
{ roleid=4, name="plain user", $$hashKey="object:223"}
]
currentRoles:
[
{ roleid=3, name="admin"}
]
Following Trys:
currentRoles.indexOf(role); // works properly and outputs 0
availableRoles.indexOf(role); // does not work
I can imagine, this occurs because of $$hasKeys. But I didn't put them there, AngularJS does augment these data.
How can I overcome this situation?
Is there a function like: ignore Angular HasKeys in this Datastructure?
Edit:
Angular object comparison:
Compare objects in Angular
So you can just write the function:
function arrayObjectIndexOf(arr, obj){
for(var i = 0; i < arr.length; i++){
if(angular.equals(arr[i], obj)){
return i;
}
};
return -1;
}
--ORIGINAL--
JavaScript saves objects as pointers, therefore, two objects even if has the same data in them, have different values (the value of the pointer in the memory).
Code example:
var role = { roleid:3, name:"admin"};
var availableRoles =
[
{ roleid:3, name:"admin"},
{ roleid:4, name:"plain user", $$hashKey:"object:223"}
];
alert(availableRoles.indexOf(role));
http://codepen.io/anon/pen/BjobaW
So it does not relate to the hashKey. To compare to objects (and such, find the index in an array) you must create a loop of comparison, or overload the "==" operator of Object to compare values and not pointers, which I dont believe you are allowed to do in JS.
Best way is not to have such objects...
You can use angular filter:
function contains(arr, id) {
return $filter('filter')(arr, {roleid : id}, true).length != 0;
}
You can use some other js library (lodash, underscore, ...) for such things.

substring from an array as3 **Error #1009: Cannot access a property or method of a null object reference

I am trying to create a matching game where one object in the array hitBoxes is matched to one object in the array hitBoxes2. I have tried to convert the instance name into a string and then used the substring method to match the LAST number in the instance name, if its a match they win. Right now I'm getting the error
TypeError: Error #1009: Cannot access a property or method of a null
object reference. at MethodInfo-499()
I'm wondering if anyone can help me. Thanks!
var left:String;
var correct:MovieClip = new Correct;
var isClicked:Boolean = false;
var leftClicked:int = 0;
p3.nextPage.buttonMode = true;
p3.nextPage.addEventListener(MouseEvent.CLICK, nextPage);
function nextPage(MouseEvent):void{
removeChild(p3);
}
var hitBoxes:Array = [p3.a1, p3.a2, p3.a3, p3.a4, p3.a5, p3.a6, p3.a7, p3.a8];
var hitBoxes2:Array = [p3.b1, p3.b2, p3.b3, p3.b4, p3.b5, p3.b6, p3.b7, p3.b8];
for (var h:int = 0; h < hitBoxes.length; h++){
hitBoxes[h].buttonMode = true;
hitBoxes[h].addEventListener(MouseEvent.CLICK, matchingLeft);
}
for (var h2:int = 0; h2 < hitBoxes2.length; h2++){
hitBoxes2[h2].buttonMode = true;
hitBoxes2[h2].addEventListener(MouseEvent.CLICK, matchingRight);
}
function matchingLeft(e:MouseEvent):void{
var left = String(e.currentTarget.name);
isClicked = true;
trace(left);
}
function matchingRight(e:MouseEvent):void{
var right:String = String(e.currentTarget.name);
trace(right);
if(isClicked == true && left.substring(3,3) == right.substring(3,3)){
trace("matched");
}
}
According to your code variable "left" is null at matchingRight method, because matchingLeft uses its local variable with name "left", and top-level "left" still has its default value.
also String.substring method is used incorrectly:
var name:String="p3.a1";
trace(name.substring(3, 3)); // this will always output empty string ""
trace(name.substring(4, 5)); // this will output "1" string
in conclusion I'd advise to use array indices (integers) instead of strings when calculating "matched" condition, substring operation and string comparison are CPU intensive.

JSON: How do I select an array inside another array?

I have the current JSON file:
[{"id":"1","images":[{"img_id":"1"},{"img_id":"2"},{"img_id":"3"}]},
[{"id":"2","images":[{"img_id":"1"},{"img_id":"2"},{"img_id":"3"}]}
How do I select the array with ID 1 and list every 'img_id' inside it, without repeating it for the other array?
edit 1:
I am trying to parse it like this but this code is erroneous:
$("#button").click(function() {
$.getJSON("../path/to/json", function(data) {
$.each(data[0].images.img_id, function(i,data){
var new_data ="<p src='path/to/folder/"+images.img_id+"'></p>";
$(new_data).appendTo("#htmlTag");
});
}); return false;
});
Much appreciated.
You have an array of objects, where each object contains another array of objects. I'm assuming the JSON structure you are using is:
var a = [{"id":"1","images":[{"img_id":"1"},{"img_id":"2"},{"img_id":"3"}]},
{"id":"2","images":[{"img_id":"1"},{"img_id":"2"},{"img_id":"3"}]}];
I'm also assuming you are using JavaScript.
PostEdit:
Your code is fairly close, I believe what I have below should work:
$("#button").click(function() {
$.getJSON("../path/to/json", function(data) {
$.each(data[0].images, function(i,data){
var new_data ="<p src='path/to/folder/" + data.img_id + "'></p>";
$(new_data).appendTo("#htmlTag");
});
});
return false;
});
All I did was change the first parameter to your each call from: data[0].images.img_id to: data[0].images. Also, I changed the declaration of new_data from:
var new_data ="<p src='path/to/folder/"+images.img_id+"'></p>";
to:
var new_data ="<p src='path/to/folder/"+data.img_id+"'></p>";
Note that the parameter "data" in the each callback function is simply the element in the array, while "i" is the index of that element in the array. Therefore, data is an object which looks like this:
{"img_id":1}
So, you can get the ID via data.img_id. Hope this helps.
I think you're talking about references. I don't think they are possible in JSON. In case you strictly need them and still want the readable serialization of your objects - I'd suggest you to look into YAML
I think there is a typo in your JSON...it seems like a bracket is missing at the end, and one has been added at the start of line 2. But, assuming you meant this (and are using Javascript):
var myJson = [{"id":"1","images":[{"img_id":"1"},{"img_id":"2"},{"img_id":"3"}]},
{"id":"2","images":[{"img_id":"1"},{"img_id":"2"},{"img_id":"3"}]}];
then you can access whatever you need just like a nested Javascript object. If you wanted to only access the object with ID equal to 1, and order is not guaranteed, you would have to iterate:
for(var i = 0; i < myJson.length; i++){
if(myJson[i].id === "1"){
var imgs = myJson[i].images;
for(var j = 0; j < imgs.length; j++){
//do what you want with imgs[j].img_id
}
}
}

Resources