I want to rename the factORLossTree into savefactORLossTree dynamically inside the function from below payload.
I am getting below data on payload after submitting the form.
{
"cluster":"Europe",
"factory":"Caivano",
"factoryId":"Caivano",
"factORLossTree":[
{
"skuid":"000000000067334539",
"skuDescription":"MAG 55ml Mini PistHazelnut 8MP x6x120 EB",
"levelLosses":[
{
"level1":"Line Scheduling Losses",
"variancePer":100
}
],
"isRowChecked":false
}
],
"submitType":"po"
}
Below is my code .
saveOrUpdateORData() {
const formData = Object.assign({}, this.orLosstreeForm.value);
if (formData.factORLossTree.length === 0) {
this.dialogService.openDialog('Data Not Available');
return false;
}
console.log(formData,"formdata");
return;
}
Expected Output
{
"cluster":"Europe",
"factory":"Caivano",
"factoryId":"Caivano",
"savefactORLossTree":[
{
"skuid":"000000000067334539",
"skuDescription":"MAG 55ml Mini PistHazelnut 8MP x6x120 EB",
"levelLosses":[
{
"level1":"Line Scheduling Losses",
"variancePer":100
}
],
"isRowChecked":false
}
],
"submitType":"po"
}
Can anyone please help me to do this.
Sure thing! Worth mentioning that this issue is purely JS and has nothing to do with your framework (e.g. - Angular)
To the point: let's assume that your payload is stored in a variable called payload
First - check if the property exists. Then - replace it:
const propertyName = 'put the property name here'
const newPropertyName = 'put the new property name here'
if (payload.hasOwnProperty(propertyName)) {
payload[newPropertyName] = payload[propertyName]
delete payload[propertyName]
}
Why this is working? Because we are creating another reference to the original data before deleting the property. At the end we end-up with one reference having the updated name
If (from some reason) you need to clone the data, follow this pattern instead:
if (payload.hasOwnProperty(propertyName)) {
const clone = JSON.parse(JSON.stringify(payload[propertyName]))
payload[newPropertyName] = clone
delete payload[propertyName]
}
I assume that your property always contains an object. If the type of the property is primitive (e.g. - number, string or boolean) you can just skip the cloning phase all together (primitives are copied by their values while only objects are handled by their reference)
Related
I have a realm Organization and Ticket. An organization has many tickets. So to update organization, it looks like this:
try {
realm.write(() => {
realm.create('Organization', {
id: organization.id,
name: organization.name,
ticket: downloadTickets(organization.id)
}
, true)
})
console.log("inserting/updating ogranization")
} catch(err) {
console.warn(err)
}
The downloadTickets function returns an array of objects. This will work on my initial write. But if I want to update the array, I want to add objects to the array but not overwrite the whole array. How can I do this without getting the current values, appending it to the new ones, and returning it to the object? That seems too slow.
When you use create() with the true parameter you are overwriting the properties of the existing object. What you want is to modify the existing data.
To do this you'll have to reference the original array in some fashion. You can either iterate over the new Tickets and push() them into the array, or use concat() on the existing array and passing in the new array.
try {
realm.write(() => {
var org = realm.create('Organization', {
id: organization.id,
name: organization.name
}
, true)
// Do this
var newTickets = downloadTickets(organization.id);
for(var i = 0; i < newTickets.length; i++) {
org.ticket.push(newTickets[i]);
}
// or this
org.ticket = org.ticket.concat(downloadTickets(organization.id));
})
console.log("inserting/updating ogranization")
} catch(err) {
console.warn(err)
}
As a side note: Referencing the array does not load the whole thing into memory. The actual data of the array is only on disk until you explicitly accesses it, Realm then reads it from disk. Accessing the array to add the new Tickets is not an expensive operation.
I am trying to retrieve one particular value from within a two-levels deep object data structure. First off, though, I am saving into a variable within the function, like this:
getTargetId() {
if (this.authenticationService.isAuthenticated()) {
const userInfo = sessionStorage.getItem('currentUser');
console.log(userInfo);
}
}
From:
console.log(userInfo);
I get this back in the console:
{"token":"sometoken.value","data":{"_id":"8cd0362c0", "phone":"555-4343"...}
What I want to do is specifically pull out the "_id" value here.
I tried:
console.log(userInfo.data._id);
But then my IDE is showing me an error:
'Property '_id' does not exist on type 'string'.
How do I dig out "_id" in this case?
You are accessing it wrong
Try userInfo.data._id
In the log of your object you can see by the {} notation that data is another object, so after accessing data you can access its properties just as you would with any other object.
I also see that you are getting
'Property '_id' does not exist on type 'string'.
This could mean that you never parsed the information. To find out if this is the case this should be right:
Running->
console.log(userInfo);
Returns->
{"token":"sometoken.value","data":{"_id":"8cd0362c0", "phone":"555-4343"...}
Just after this code:
Running->
console.log(typeof userInfo);
Returns->
"string"
With your edits, I can see that this is the case.
Try:
userInfo = JSON.parse(sessionStorage.getItem('currentUser') );
console.log(userInfo.data._id);
The _id property is under the data key:
const response = {
"token":"sometoken.value",
"data": {
"_id":"8cd0362c0",
"phone":"555-4343"
}
};
console.log(response.data._id)
You can also use destructuring:
const { _id } = response.data;
console.log(_id)
or:
const { data: { _id }} = response;
console.log(_id);
So, as #jonsharpe pointed out, the key was to JSON.parse the string first. So this gets me the value I need for "_id":
getTargetId() {
if (this.authenticationService.isAuthenticated()) {
const userInfo = JSON.parse(sessionStorage.getItem('currentUser'));
console.log(userInfo.data._id);
}
}
Actually your string is returned as JSON string. So you have to parse it into object using JSON.parse() if you are using js or with $.parseJSON() if you are using Jquery. So your updated code now looks like this.
var user ='{"token":"sometoken.value","data":{"_id":"8cd0362c0", "phone":"555-4343"}}';
var k = JSON.parse(user);
alert(k.data._id);
And Fiddle is here.
Thank You
can't find whether this has been asked before or not, so bear with me.
I'm just starting to use Neo4j with a nodejs backend and the neo4j-driver driver. I wonder if it's possible to create a node with several properties without enumerating each one in the second argument to the session.run method.
app.post("/signup", function(req, res) {
var user = req.body; //{userId: "johnsmith", email: "john#smith.com", ...}
session.run("CREATE (u:User {u}) RETURN u", user).then(function(response) {
/*do stuff with newly created user*/
}, function() {
//handle error
});
});
Currently, this yields the following error: {code: 'Neo.ClientError.Statement.ParameterMissing', message: 'Expected a parameter named u' }, and if I change the above to:
app.post("/signup", function(req, res) {
var user = req.body; //{userId: "johnsmith", email: "john#smith.com", ...}
session.run("CREATE (u:User {u}) RETURN u", {u: user}).then(function(response) {
/*do stuff with newly created user*/
}, function() {
//handle error
});
});
then the error reads: { code: 'Neo.ClientError.Statement.TypeError', message: 'Property values can only be of primitive types or arrays thereof' }.
This doesn't make much sense to me, given that the refcard clearly states you can create a node using a map, like so: CREATE (n {map}); so I must obviously be getting something wrong. I hope I don't have to enumerate all a user's properties like so:
session.run("CREATE (u:User {userId: {u.userId}, email: {u.email}, ...}) RETURN u", {u: user}).then(/*...*/)
Thanks in advance
Map could not be the value of the properties
You can set properties using a parameter - http://neo4j.com/docs/developer-manual/current/cypher/clauses/set/#set-set-all-properties-using-a-parameter
So you need to check the input parameter and transform its properties if necessary.
For example:
app.post("/signup", function(req, res) {
var params = {};
//{userId: "johnsmith", email: "john#smith.com", ...}
Object.keys(req.body).forEach( function(k) {
var value = req.body[k];
if (!isPrimitive(val)) value = JSON.stringify(value);
params[k] = value;
});
session.run("CREATE (u:User) SET u = {user} RETURN u", {user: params})
.then(function(response) {
// do stuff with newly created user
}, function() {
// handle error
});
});
Where isPrimitive an abstract function that checks whether a variable is a primitive.
Neo4j only supports storing specific kinds of data structures to a property. To quote from the Cypher Refcard:
Neo4j properties can be strings, numbers, booleans or arrays thereof.
And, to be more exact, in order for an array (or "collection") to be stored as a property value, all its elements must be of the same primitive type.
The answer from #stdob-- provides one possible simple workaround to this (but it stringifies all arrays, even ones that can be stored without conversion).
NOTE: The refacrd needs to be a bit more clear. Nested maps are supported, in general. For instance, you can freely pass in JSON data as Cypher query parameters. However, maps containing nested maps are NOT supported for storing as property values.
I have a user specified JSON object that I'm attempting to process in the browser.
The problem is that it needs to match an existing object.
They can't accidentally:
forget to include some fields.
typo fields or deliberately add new fields.
Is there a way to handle this?
so basically if I have an object with foo and bar members, I want their defaults if the user's json is just {} ... and if they accidentally send something like {bart: "asdf";} (typo on 'bar') then I want it to generate an exception.
var default_object = { ... };
var allowed_keys = [ "key1", "key2", ... ];
var new_object = default_object.clone();
for (var key in json_object) {
if (json_object.hasOwnProperty(key)) {
if (allowed_keys.indexOf(key) == -1) {
// Report error here
} else {
new_object[key] = json_object[key];
}
}
}
See here for how to write the clone method I used above. If you use jQuery, you could simplify some of this code by using $.extend().
I have a Single Page Application that is working pretty well so far but I have run into an issue I am unable to figure out. I am using breeze to populate a list of projects to be displayed in a table. There is way more info than what I actually need so I am doing a projection on the data. I want to add a knockout computed onto the entity. So to accomplish this I registered and entity constructor like so...
metadataStore.registerEntityTypeCtor(entityNames.project, function () { this.isPartial = false; }, initializeProject);
The initializeProject function uses some of the values in the project to determine what the values should be for the computed. For example if the Project.Type == "P" then the rowClass should = "Red".
The problem I am having is that all the properties of Project are null except for the ProjNum which happens to be the key. I believe the issue is because I am doing the projection because I have registered other initializers for other types and they work just fine. Is there a way to make this work?
EDIT: I thought I would just add a little more detail for clarification. The values of all the properties are set to knockout observables, when I interrogate the properties using the javascript debugger in Chrome the _latestValue of any of the properties is null. The only property that is set is the ProjNum which is also the entity key.
EDIT2: Here is the client side code that does the projection
var getProjectPartials = function (projectObservable, username, forceRemote) {
var p1 = new breeze.Predicate("ProjManager", "==", username);
var p2 = new breeze.Predicate("ApprovalStatus", "!=", "X");
var p3 = new breeze.Predicate("ApprovalStatus", "!=", "C");
var select = 'ProjNum,Title,Type,ApprovalStatus,CurrentStep,StartDate,ProjTargetDate,CurTargDate';
var isQaUser = cookies.getCookie("IsQaUser");
if (isQaUser == "True") {
p1 = new breeze.Predicate("QAManager", "==", username);
select = select + ',QAManager';
} else {
select = select + ',ProjManager';
}
var query = entityQuery
.from('Projects')
.where(p1.and(p2).and(p3))
.select(select);
if (!forceRemote) {
var p = getLocal(query);
if (p.length > 1) {
projectObservable(p);
return Q.resolve();
}
}
return manager.executeQuery(query).then(querySucceeded).fail(queryFailed);
function querySucceeded(data) {
var list = partialMapper.mapDtosToEntities(
manager,
data.results,
model.entityNames.project,
'ProjNum'
);
if (projectObservable) {
projectObservable(list);
}
log('Retrieved projects using breeze', data, true);
}
};
and the code for the partialMapper.mapDtosToEntities function.
var defaultExtension = { isPartial: true };
function mapDtosToEntities(manager,dtos,entityName,keyName,extendWith) {
return dtos.map(dtoToEntityMapper);
function dtoToEntityMapper(dto) {
var keyValue = dto[keyName];
var entity = manager.getEntityByKey(entityName, keyValue);
if (!entity) {
extendWith = $.extend({}, extendWith || defaultExtension);
extendWith[keyName] = keyValue;
entity = manager.createEntity(entityName, extendWith);
}
mapToEntity(entity, dto);
entity.entityAspect.setUnchanged();
return entity;
}
function mapToEntity(entity, dto) {
for (var prop in dto) {
if (dto.hasOwnProperty(prop)) {
entity[prop](dto[prop]);
}
}
return entity;
}
}
EDIT3: Looks like it was my mistake. I found the error when I looked closer at initializeProject. Below is what the function looked like before i fixed it.
function initializeProject(project) {
project.rowClass = ko.computed(function() {
if (project.Type == "R") {
return "project-list-item info";
} else if (project.Type == "P") {
return "project-list-item error";
}
return "project-list-item";
});
}
the issue was with project.Type I should have used project.Type() since it is an observable. It is a silly mistake that I have made too many times since starting this project.
EDIT4: Inside initializeProject some parts are working and others aren't. When I try to access project.ProjTargetDate() I get null, same with project.StartDate(). Because of the Null value I get an error thrown from the moment library as I am working with these dates to determine when a project is late. I tried removing the select from the client query and the call to the partial entity mapper and when I did that everything worked fine.
You seem to be getting closer. I think a few more guard clauses in your initializeProject method would help and, when working with Knockout, one is constantly battling the issue of parentheses.
Btw, I highly recommend the Knockout Context Debugger plugin for Chrome for diagnosing binding problems.
Try toType()
You're working very hard with your DTO mapping, following along with John's code from his course. Since then there's a new way to get projection data into an entity: add toType(...) to the end of the query like this:
var query = entityQuery
.from('Projects')
.where(p1.and(p2).and(p3))
.select(select)
.toType('Project'); // cast to Project
It won't solve everything but you may be able to do away with the dto mapping.
Consider DTOs on the server
I should have pointed this out first. If you're always cutting this data down to size, why not define the client-facing model to suit your client. Create DTO classes of the right shape(s) and project into them on the server before sending data over the wire.
You can also build metadata to match those DTOs so that Project on the client has exactly the properties it should have there ... and no more.
I'm writing about this now. Should have a page on it in a week or so.