1

I have searched my many online articles of parsing json array or there exists any npm package to do it.But my all efforts gone in vain.

I have an json array like this =>

{
    "pctProjects": [
      {
        "ID": "1",
        "Name": "Software Upgrade",
        "Desc": "GO! V1 Chapter 5- EOC Mastery Exercise",
        "AppId": "1",
        "UserId": "1",
        "CreatedDate": "2008-07-30T00:00:00",
        "Score": "100",
        "SeriesID": "2",
        "IsPublished": "1",
        "PublishedLMSVariationID": "5",
        "IsPCTActive": "0",
        "IVTEnabled": "0",
        "IsActiveInSelectPopup": "1",
        "Chapter": "CH05"
      },
      {
        "ID": "2",
        "Name": "Business Venture",
        "Desc": "Exploring Volume 1 Chapter 3- TST Exercise",
        "AppId": "1",
        "UserId": "1",
        "CreatedDate": "2008-07-30T00:00:00",
        "Score": "100",
        "SeriesID": "1",
        "IsPublished": "1",
        "PublishedLMSVariationID": "7",
        "IsPCTActive": "0",
        "IVTEnabled": "0",
        "IsActiveInSelectPopup": "1",
        "Chapter": "CH03"
      }
      .
      .
      .

I looped through my json array "pctProjects" using Json.parse method and able to find the object using the property PublishedLMSVariationID which i need to replace with another value, i'm using filesystem module functions like appendFileSync() and writeFileSync() to update the file.But using this methods i have to rewrite other objects data also which i'm not changing and this is not optimised method to do this as i can have n no of objects in that array.

And Using replace-in-file also not helping me to achieve my goal.

Also adding my code snippet what i'm doing right now which is not optimised.

for(let item of gulpJson.pctProjects){
        // console.log(typeof touseVariationId)
        if(counter==1 && item.PublishedLMSVariationID == results[0]){
            item.PublishedLMSVariationID = results[1]
            fs.writeFileSync(path.join(dir,'PCT5_MasterPCTProjectsForGulp.json'), JSON.stringify(item,null,4));
            counter++;
        }
        else if(counter==1 && item.PublishedLMSVariationID != results[0]){
            fs.writeFileSync(path.join(dir,'PCT5_MasterPCTProjectsForGulp.json'), JSON.stringify(item,null,4));
            counter++;      
        }
        else if(item.PublishedLMSVariationID == results[0]){

            item.PublishedLMSVariationID = results[1]
            fs.appendFileSync(path.join(dir,'PCT5_MasterPCTProjectsForGulp.json'), JSON.stringify(item,null, 4));
            // break
            // fs.writeFileSync(path.join(dir,'PCT5_MasterPCTProjectsForGulp.json',null, 2), JSON.stringify(item));
        }
        else
            fs.appendFileSync(path.join(dir,'PCT5_MasterPCTProjectsForGulp.json'),","+"\n"+"\t"+  JSON.stringify(item,null, 4));
    }

Questions:

  1. Is there any way to just replace my one json property in json array in nodejs???

Much Obliged:).Thanks in advance.

Please comment if any more information is needed.

sagg1295
  • 177
  • 2
  • 11
  • _How to just replace my one property of json object in json array which have large no of json objects in nodejs_ really unclear about what you are asking for. Your there is just an array of objects of equal number of properties what I see – Muhammad Usman May 09 '18 at 08:16
  • If you're asking how to somehow parse the file without loading it into RAM first, that's not how computers work I'm afraid. What you want to do is not possible without loading the entire file, changing it, then writing it back to the HD. –  May 09 '18 at 08:19
  • @GeorgeBailey, i need to replace just one property of one json object and so i only want to replace that property in file not rewrite everything in file. – sagg1295 May 09 '18 at 09:45
  • Surely, reading the entire file, updating the value, then writing the entire file will take much less time than opening, writing and closing a file hundreds or even thousands of times...? –  May 09 '18 at 09:55
  • @ChrisG,why are you telling me this,I know this. I'm asking of do this. – sagg1295 May 09 '18 at 10:01
  • @sagg1295 If you know this, why are you using a vastly more inefficient and buggy method, as seen in your question's code snippet, which creates non-valid JSON? Have you *tried* writing the entire file yet? If not, why not? Also, editing a file in place on the hard drive would require direct access on the "ground layer". I'm 99% certain you can't do that with node.js, and it's *not necessary* either. –  May 09 '18 at 15:19
  • @ChrisG,I'm appending nodes after this loop and making it a valid json. – sagg1295 May 10 '18 at 05:00
  • @sagg1295 If you say so; but the loop looks like you're definitely missing at least one comma. Also, why ignore my other questions? Never mind. –  May 10 '18 at 09:36
  • @ChrisG,please can i now ask why have you given me negative vote for this question. – sagg1295 May 10 '18 at 10:17
  • @sagg1295 Because you're using an extremely bad solution right now, and asking for an impossible one in order to improve it, while ignoring the two realistic and much better alternatives (read/write entire file, use DB). Plus you act like you already know more than we do when you obviously don't. It's what Germans call "learn resistant". –  May 10 '18 at 10:26
  • @ChrisG,first have you read my question completely ,in the end i have written is it possible to do that what i'm asking here.First read the question properly,then put any allegation on me.For your kind information this is possible by using replace npm module . – sagg1295 May 10 '18 at 12:12
  • @sagg1295 I did read your entire question, and what you have written at the end, taken at face value, was answered by Chirag. - Also, I'll bet the `replace` module will again 1. load the entire file, 2. replace stuff, 3. write the entire file, which is what you *have* to do without low level access to the hard drive. Something you are stubbornly refusing to accept. –  May 10 '18 at 13:04

2 Answers2

1

From what I understand, you are asking if You can edit your JSON file on the file system differentially without rewriting the whole thing. Although I'm sure that that is possible, I would recommend simply rewriting your entire JSON file each time you want to update it. If the JSON is so huge that this becomes too tedious/time consuming, you may be better off using a DB of some sort (MySQL, Mongo, Firebase etc).

My recommendation would be to do it in the following order:

  1. Retrieve JSON string from file (lets call it source.json)
  2. Parse JSON string to get Object using JSON.parse
  3. Update the object you want to update in the parsed object by looping over it and overwriting values as needed.
  4. Use JSON.stringify to get back a string representation (of the entire object as obtained in step 2) and overwrite your source.json with the new JSON
Chirag Ravindra
  • 4,760
  • 1
  • 24
  • 35
  • Your "recommendation" is what OP is already doing, as described in their post. –  May 09 '18 at 08:29
  • 1
    @ChrisG actually, I don't think this is what the OP is doing. Correct me if I'm wrong but in the code shared, they are stringifying only one object at a time and using that to append to the file which I believe will cause the resulting JSON file to be invalid JSON. – Chirag Ravindra May 09 '18 at 08:31
  • 1
    Sorry, you're right, they're actually writing it out object by object... I should've looked at their code more closely. –  May 09 '18 at 09:54
  • @ChiragRavindra,what is the use of this ,this is same what i'm doing.I just want to replace only one property ,this method is not what I want. – sagg1295 May 09 '18 at 10:04
  • @sagg1295 this is a little different from what you are doing in the sense that the write to files happen as a whole JSON objects which guarantees that the JSON file contains a valid JSON. Your method incrementally adds objects which may cause the JSON to become invalid (see my other comment). Whether you want to replace one property or many, this is a straightforward way of doing it. IT IS INEFFICIENT but not because of this method but because we are using the file system as a persistence layer when a DB might be a better fit. – Chirag Ravindra May 09 '18 at 10:11
  • @ChiragRavindra,here i not using any DB.I'm just passing value of Id to be changed from frontend and changing that by using fs module on local files. – sagg1295 May 09 '18 at 10:15
  • @sagg1295 I understand that. What exactly do you feel is lacking in this method? I'm trying to understand why this is not the solution you need. – Chirag Ravindra May 09 '18 at 10:16
  • @ChiragRavindra,I want to replace the property of that object and rewrite only that part of file.I dont want to rewrite all of the json object again in that file – sagg1295 May 09 '18 at 10:18
  • @sagg1295 Okay. So the main problem is that this solution rewrites the entire file and you want it to change only the part which is edited. As stated in my answer, this is possible to do but not ver efficient or scalable. And if you JSON is not too big, the benefit will almost be zero. I'm sorry my answer did not help. What you are trying to do is possible but will require a lot more work to calculate where in the file to start the write and which part of the file to remove. This method is better in my humble opinion. Good luck :) – Chirag Ravindra May 09 '18 at 10:23
  • @ChiragRavindra,can you share any link where i can find tha\is option to able to change just one edited field. – sagg1295 May 09 '18 at 10:31
  • Tried looking around but most content on this topic suggests the same method as I have. [See this other question on StackOverflow](https://stackoverflow.com/questions/14177087/replace-a-string-in-a-file-with-nodejs). The accepted answer has a comment asking the same question you have and the answer to that is similar to my reply - "I'm sure there is a node_module to do this but I don't know" – Chirag Ravindra May 09 '18 at 12:13
1

I am able to achieve my result in an optimised way by using the npm replace-in-file module.

Here, is my code snippet where i have used that module:

replace.sync({
        files: path.join(dir,'PCT5_MasterPCTProjectsForGulp1.json'),
        from: results[0],
        to: results[1]
    });
sagg1295
  • 177
  • 2
  • 11