Object Compare in AngularJS - javascript

I have a form which when loaded sends GET request to server and recives data which will stored in 'master' and i copy that data to 'local' as below.
$scope.dirty = false;
init(data);
function init(data) {
$scope.master = angular.copy(data.data);
$scope.local = angular.copy($scope.master);
}
Now, I use local object as model for my form and I have to button submit and reset. I watch the local object as below.
$scope.$watchCollection('local', function (newLocal, oldLocal) {
$scope.dirty = !angular.equals(newLocal, $scope.master);
});
So, If dirty is true then i can know that data has been modified but since I am using Objects AngularJS adds $$hasKey to $scope.local and because of that $scope.dirty always sets to true.
So, is there any way to handle this problem? I am new to AngularJS so may be this can be funny question but I'm stuck.

You could convert your object to a JSON string before comparing:
function init(data) {
// store json data into $scope.master for later comparison
$scope.master = angular.toJson(data.data);
$scope.local = angular.copy(data.data);
}
$scope.$watchCollection('local', function (newLocal, oldLocal) {
var json = angular.toJson(newLocal); // new local without $$ key
$scope.status.dirty = !angular.equals(json, $scope.master);
// $scope.local is still a javascript object
});

I was sending data form PHP and PHP treats Number and string as seperate datatype.
So I converted those Number data to string and now It works as desired and also I leart that whenever I use <form name='newForm> angularJS creates a new scope named newForm so that I can you many properties of that scope like $dirty, $pristinem $submitted and many more. so Now I dont have to write this logic by myself

Related

Parse JSON data, and then pass all its values to another function

I'm building this website: http://collections.design
The way it works is by reading all tools data from a JSON, using jQuery (I don't know much javascript). Then, you can click on an item and a side panels opens with further information. But there's a lot of repeated code, so I'm trying to optimise it a bit.
First I parse the JSON:
// The data source
var data_source = "../data/tools/tools.json";
// Parsing the JSON
$.getJSON(data_source, function(data) {
$.each(data, function(key,val) {
// And I'm storing all of its values in variables, to make them easier to read:
var name = val.availability.name;
var linux = val.os.linux;
// Then I'm using all that to render each item on screen
…
});
});
Each of the items has a button that calls another function to create and open the side panel. The side panel reuses that item's data from the JSON. This function to create the side panel is using the name variable as parameter, but then inside is parsing the JSON again to get the rest of the values it needs.
My question is:
How can I "encapsulate" all variables when I do the JSON parsing, then pass it as a parameter to the other function; and finally, individually read each of those values in the other function?
I tried working with arrays. But didn't manage it to work, also keeping in mind that I'm trying to simplify things, not repeat myself, and keep short names…
Maybe I'm asking too much, but any pointers or links to doc will be appreciated.
I see two ways of doing this.
1) Save the JSON data outside the scope so you can reuse it and pass the index of the data you want.
Something like this
// The data source
var data_source = "../data/tools/tools.json";
var all_data;
// Parsing the JSON
$.getJSON(data_source, function(data) {
all_data = data;
$.each(data, function(key,val) {
$('.button').on('click', function() { callToOtherFunction(key) })
});
});
function callToOtherFunction(key) {
console.log(all_data[key]);
}
2) As Sam Axe said, pass the data directly to the function
// The data source
var data_source = "../data/tools/tools.json";
// Parsing the JSON
$.getJSON(data_source, function(data) {
$.each(data, function(key,val) {
$('.button').on('click', function() { callToOtherFunction(key) })
});
});
function callToOtherFunction(val) {
console.log(val);
}
Here's a working fiddle.
The data is already "encapsulated" in the data object. Pass that object to the function that you want to use the data in.
You could always construct a new object - but what's the point - it's already in the data object.

Pass array of objects from JS to ASP.NET controller

I'm having problem with passing the array of objects as mentioned above.
The code generally works, but when I pass the data only 1st object goes further.
I'm a total noob at .js/JSON parsing and would be grateful for guidance.
Also if you have any data on approach towards dynamic forms/JSON parsing in asp.net mvc that would help. I've been scouting internet for a few days now and can't find solution that has all the things I require.
Thanks!
controller that takes json data:
public ActionResult JsonResult(object[] json)
{
TempData["json"] = json;
return View();
}
javascript taking input data from all elements (also those dynamiclly added):
<script>
$(document).on('submit', '.simple-form', function (e) {
getValues(this);
e.preventDefault();
})
var getValues = function (currForm) {
var formData = $(currForm).serializeArray();
//object Array - all values present, though
// each value from a row is stored in other object meaning
// that row having prop1,prop2,prop3 isnt stored in 1 object,
// 3 rows generate 9 objects (each has 3 properties)
console.log(formData);
//here I try to pass JSON to MVC controller
'#Url.Action("JsonResult", "Session", new { json = "formData" })';
</script>

How to reuse JSON Object

Scenario:
The MVC web page gets JSON object with lots of data. Upon click of button (there are quiet a number of buttons) I would like to reuse this JSON object and select required JSON Properties (without making a request to server).
It's not HTML5 so can't use browser local storage. At the moment I'm storing the JSON object on GLOBAL variable and reusing it.
Are there any elegant options available to store and re-use returned JSON object on client side?
Just cache the data. There is no need to store the JSON in a global variable, I'm sure you'll find a place in your MVC application to scope a local variable. You will have implemented a getter function for the data with a callback. With caching, it'll look like this:
var getData = (function(){
var cache;
var loading = false;
var callbacks = [];
return function(callback) {
if (typeof cache != "undefined")
callback(cache);
else {
callbacks.push(callback);
if (!loading) {
loading = true;
doSingleHeavyAjaxCall(options, function success(data) {
cache = data;
for (var cb; cb = callbacks.shift();)
cb(cache);
});
}
}
};
})();
Then use getData(function callback(data){...}) as often as you want, and it will only trigger one ajax request.
Another option to Jakubs answer is creating a global variable that you can update and retrieve as you like on the page.
Global variables get attached to the window object, so just write this in your <head> section.
<script type="text/javascript">
window.jsonData = {};
</script>
Then wherever you're retrieving your data just update that object.
<script type="text/javascript">
$.ajax(..., function(data) {
window.jsonData = data;
});
</script>
Then you can use it wherever you like in your code on that page.
<script type="text/javascript">
console.dir(jsonData);
</script>
You can store the object in data- attribute of some element - preferably container for the part of your page that represents your data (table, grid):
var json = {};
$('#mygrid').data('mydata', json);
You can retrieve it later
var json = $('#mygrid').data('mydata')
jQuery data() method documentation: http://api.jquery.com/data/

how to serialize a form without jQuery? [duplicate]

This question already has answers here:
form serialize javascript (no framework)
(25 answers)
Closed 8 years ago.
For a lot of reasons (first of all: learning javascript), I need to serialize a form without jQuery, and send the resulting serialized data-structure to a php page with ajax.
The serialized data must be in JSON format.
How can I do that?
--EDIT--
this is how my form looks like: http://jsfiddle.net/XGD4X/
I am working on a similar problem, and I agree that it is worthwhile to learn how to program first without using a framework. I am using a data object (BP.reading) to hold the information, in my case a blood pressure reading. Then the JSON.stringify(dataObj) dose the work for you.
Here is the handler for the 'save' button click, which is a method on the dataObj. Note I am using a form instead of a table to input data, but the same idea should apply.
update: function () {
var arr = document.getElementById("BP_input_form").firstChild.elements,
request = JDK.makeAjaxPost(); // simple cross-browser httpxmlrequest with post headings preset
// gather the data and store in this data obj
this.name = arr[0].value.trim();
...
this.systolic = arr[3].value;
this.diastolic = arr[4].value;
// still testing so just put server message on page
request.callback = function (text) {
msgDiv.innerHTML += 'server said ' + text;
};
//
request.call("BP_update_server.php", JSON.stringify(this));
}
I hope this is helpful
* edit to show generic version *
In my program, I am using objects to send, receive, display, and input the same kind of data, so I already have objects ready. For a quicker solution you can just use a empty object and add the data to it. If the data is a set of the same type of data then just use an array. However, with a object you have useful names on the server side. Here is a more generic version untested, but passed jslint.
function postUsingJSON() {
// collect elements that hold data on the page, here I have an array
var elms = document.getElementById('parent_id').elements,
// create a post request object
// JDK is a namespace I use for helper function I intend to use in other
// programs or that i use over and over
// makeAjaxPost returns a request object with post header prefilled
req = JDK.makeAjaxPost(),
// create object to hold the data, or use one you have already
dataObj = {}, // empty object or use array dataArray = []
n = elms.length - 1; // last field in form
// next add the data to the object, trim whitespace
// use meaningful names here to make it easy on the server side
dataObj.dataFromField0 = elms[0].value.trim(); // dataArray[0] =
// ....
dataObj.dataFromFieldn = elms[n].value;
// define a callback method on post to use the server response
req.callback = function (text) {
// ...
};
// JDK.makeAjaxPost.call(ULR, data)
req.call('handle_post_on_server.php', JSON.stringify(dataObj));
}
Good Luck.
CoffeeScript implementation returning a GET query string:
serialize = (form) ->
enabled = [].filter.call form.elements, (node) -> not node.disabled
pairs = [].map.call enabled, (node) ->
encoded = [node.name, node.value].map(encodeURIComponent)
encoded.join '='
pairs.join '&'
Or if you rather prefer a key-value map:
serialize = (form) ->
data = {}
for node in form.elements when not node.disabled and node.name
data[node.name] = node.value
data
I haven't looked at jQuery's implementation, so no 100% compatibility guaranteed.

Can't access page-wide javascript variable

I'm fetching a JSON response and with that response, I have two values:
Air shipment cost.
Land shipment cost.
I want to save those two values somewhere in the client so that when a user chooses either 1 radio button or the other, I add that value to another element on the page.
Here's what I'm doing:
<script type="text/javascript">
$(document).ready(function () {
var landCost;
var airCost;
$("#ddlCiudad").change(function () {
var idCity = $("#ddlCiudad").val();
$.getJSON("/ProductCheckout/GetPriceForLocation", { cityId: idCity, productId: idProduct, type: "land" },
function (cityData) {
console.log("Recieved json data."); //This part works. It outputs.
var data = $.parseJSON(cityData);
console.log("Parse JSON response."); //This part works. It outputs.
landCost = data.LandCost;
console.log("Assigned value of LandCost"); //FAILS HERE. nothing is shown. not even an error.
airCost = data.AirCost;
console.log("Assigned value of AirCost");
alert(landCost);
console.log("Alerted land!");
alert(airCost);
console.log("Alerted air!");
}
);
});
So what do you suggest? I need to have the values of this JSON response, available for usage on that page, if I declare the variable inside the change() event, it'll be out of scope.
{"DaysToShip":" TER = 48 Hrs / AER = 24 Hrs","LandCost":"25,00","AirCost":""}
try
landCost = cityData.LandCost;
If you really must use global variables, you can attach them directly to the window object.
window.airCost = cityData.AirCost;
Really though you want to have the json request and the 'radio button' handling in the same scope, so that you're not polluting the global namespace at all.
Your call to $.parseJSON() is returning null because the data passed to your callback has already been parsed to JSON.
var json = {LandCost:3, AirCost:5},
results = $.parseJSON(json);
console.log(results); // results == null
IF you want to globally declare your variables, either put them outside the jQuery closure ($(document).ready(function () {...});), or don't use var to declare them. If you don't use the var keyword the variable will default to a global.
Here is a jsfiddle of setting global variables without using the var keyword: http://jsfiddle.net/jasper/JWtbV/
Have you considered using jQuery's $.data() function to attached the values directly to the body element in the DOM and accessing it from there?
// Set Values
$('body').data('landCost', data.LandCost);
$('body').data('airCost', data.AirCost);
// Retrieve Values //
console.log($('body').data('landCost');
console.log($('body').data('airCost');
Hope it helps.

Categories