8000 ConvertTo-JSON should allow nesting 0 · Issue #13660 · PowerShell/PowerShell · GitHub
[go: up one dir, main page]

Skip to content

ConvertTo-JSON should allow nesting 0 #13660

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
PrzemyslawKlys opened this issue Sep 19, 2020 · 19 comments
Closed

ConvertTo-JSON should allow nesting 0 #13660

PrzemyslawKlys opened this issue Sep 19, 2020 · 19 comments
Labels
Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Resolution-Fixed The issue is fixed. WG-Cmdlets-Utility cmdlets in the Microsoft.PowerShell.Utility module

Comments

@PrzemyslawKlys
Copy link
PrzemyslawKlys commented Sep 19, 2020

There seems to be an oversight of what ConvertTo-JSON allows when it comes to nesting. Since the default value is 2 (not 0) it's impossible to set it to 0, as minimal value is 1.

Steps to reproduce

[PSCustomObject] @{
    Test  = 1
    Test2 = 2
    Test3 = [PSCustomObject] @{
        IdontWantThat = 1
    }
} | ConvertTo-Json -Depth 0

Expected behavior

[PSCustomObject] @{
    Test  = 1
    Test2 = 2
    Test3 = [PSCustomObject] @{
        IdontWantThat = 1
    }
} | ConvertTo-Json -Depth 0

Should be:

{
"Test":"1",
"Test2":"2",
"Test3":"@{IDontWantThat=1}"}

or similar

Actual behavior

[PSCustomObject] @{
    Test  = 1
    Test2 = 2
    Test3 = [PSCustomObject] @{
        IdontWantThat = 1
    }
} | ConvertTo-Json -Depth 0
ConvertTo-Json : Cannot validate argument on parameter 'Depth'. The 0 argument is less than the minimum allowed range of 1. Supply an argument that is greater than or equal to 1 and then try the command again.

Environment data


@PrzemyslawKlys PrzemyslawKlys added the Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a label Sep 19, 2020
@PrzemyslawKlys PrzemyslawKlys changed the title ConvertTo-JSON doesn't allow nesting 0 ConvertTo-JSON should allow nesting 0 Sep 19, 2020
@iSazonov iSazonov added the WG-Cmdlets-Utility cmdlets in the Microsoft.PowerShell.Utility module label Sep 19, 2020
@kvprasoon
Copy link
Contributor

@iSazonov Are we okay to change min to 0 ?

@iSazonov
Copy link
Collaborator

I hope we will to move to new .Net JSON API in next milestone (7.2 LTS). In the time we will review all JSON cmdlet's issues. I expect we will get many minor and major (breaking) changes.

If the request is to make a shift 1->0, 2->1 and so on it is a breaking change. I don't see a value in the change as standalone but among many other breaking changes, this could be favored.

@iSazonov iSazonov added the Breaking-Change breaking change that may affect users label Sep 25, 2020
@kvprasoon
Copy link
Contributor
kvprasoon commented Sep 25, 2020

I think the request is just only to make min depth value to 0.

@PrzemyslawKlys
Copy link
Author

Yep, the request is allow 0 instead of 1 as minimum value. Pretty sure it's not breaking change as long as it behaves correctly.

@vexx32 vexx32 removed the Breaking-Change breaking change that may affect users label Sep 25, 2020
@vexx32
Copy link
Collaborator
vexx32 commented Sep 25, 2020

Yeah, allowing a lower minimum shouldn't break anything.

@iSazonov
Copy link
Collaborator

With Depth 2 we get

{
  "Test": 1,
  "Test2": 2,
  "Test3": {
    "IdontWantThat": 1
  }
}

With Depth 1

{
  "Test": 1,
  "Test2": 2,
  "Test3": {
    "IdontWantThat": 1
  }
}

So with Depth 0:

{
}

@iSazonov
Copy link
Collaborator

Yeah, allowing a lower minimum shouldn't break anything.

It seems we already discussed this - truncating is data lost - it is bad.

@vexx32
Copy link
Collaborator
vexx32 commented Sep 25, 2020

Depth 0 should have:

{
  "Test": 1,
  "Test2" : 2,
  "Test3": "{IdontWantThat=1}"
}

As for truncating data, sure. This is an opt in mechanism. Nothing existing will break.

@kvprasoon
Copy link
Contributor

Depth 0 with code change has

{
  "Test": 1, 
  "Test2": 2,
  "Test3": "@{IdontWantThat=1}"
}

@PrzemyslawKlys
Copy link
Author

I am using ConvertTo-Json to generate javascript data.

$Data = [PSCustomObject] @{
    Test  = 1
    Test2 = 2
    Test3 = [PSCustomObject] @{
        IdontWantThat = 1
    }
}

New-HTML {
    New-HTMLTable -DataTable $Data -DataStore JavaScript
} -FilePath $Env:USERPROFILE\Desktop\test.html -ShowHTML

Aside from having unusable data - that is not displayed anyway, the file size gets much larger.

image

I've rolled out my own ConvertTo-JsonLiteral which solves this in 5.1 but I would appreciate the issue being fixed in PowerShell 7 so in the future users can decide what to do.

This is how it looks inside HTML
image

As @vexx32 said this is opt-in so no loss of data unless you specifically ask for it. One could argue that putting default at 2, makes anything over 2 at the same disadvantage as having 0 for nest 8000 ing of 1.

@iSazonov
Copy link
Collaborator

What is an output difference in Depth 0 and Depth 1?

@vexx32
Copy link
Collaborator
vexx32 commented Sep 27, 2020

Depth 1:

{
  "Test": 1,
  "Test2": 2,
  "Test3": {
    "IdontWantThat": 1
  }
}

Depth 0:

{
  "Test": 1, 
  "Test2": 2,
  "Test3": "@{IdontWantThat=1}"
}

@iSazonov
Copy link
Collaborator

@vexx32 Thanks! I don't see a value in this. From other discussions current intention is to follow new .Net API behavior - remove default depth, throw on truncating by default.

@vexx32
Copy link
Collaborator
vexx32 commented Sep 27, 2020

🤷 clearly someone does, or we wouldn't have this issue. 😂

@PrzemyslawKlys
Copy link
Author
PrzemyslawKlys commented Sep 27, 2020

It's even worse for DateTime...

[PSCustomObject] @{
    Test  = 1
    Test2 = 2
    Test3 = [PSCustomObject] @{
        IdontWantThat = Get-Date
    }
} | ConvertTo-Json -Depth 1
{
    "Test":  1,
    "Test2":  2,
    "Test3":  {
                  "IdontWantThat":  {
                                        "value":  "\/Date(1601231994118)\/",
                                        "DisplayHint":  2,
                                        "DateTime":  "niedziela, 27 września 2020 20:39:54"
                                    }
              }
}

It's useless to my use case. While I understand you don't want to truncate data I have no way to show this data in one dimension view outside of PowerShell. It just adds junk that I don't need.

This is what my version of ConvertTo-JsonLiteral does

{
"Test":1,
"Test2":2,
"Test3":{
"IdontWantThat":"2020-09-27 20:42:01"}}

And with depth 0

{
"Test":1,
"Test2":2,
"Test3":"@{IdontWantThat=09/27/2020 20:42:27}"}

And this is also an idea for what I would like from New Convert-ToJson. Ability to define DateTime format just like you have added the ability for enum.

Output for Depth 1 for Date or INT:

image

Output for Depth 0

image

At least I can see something and act. I want ConvertTo-JSON to act a bit like ConvertTo-HTML where it does what I'm asking for.

@TravisEz13
Copy link
Member

What is the value of this behavior?

@TravisEz13 TravisEz13 added the Review - Maintainer The PR/issue needs a review from the PowerShell repo Maintainers label Mar 22, 2021
@PrzemyslawKlys
Copy link
Author
PrzemyslawKlys commented Mar 22, 2021

I explained it multiple times already - is it not clear? I even responded to your question in the old pull request. I also show the problem above.

@TravisEz13
Copy link
Member

@PrzemyslawKlys I see no explanation of the value of the behavior. Just the fact that it can generate a flat json. What would you do with the flat json? Why? When?

@PrzemyslawKlys
Copy link
Author

@TravisEz13 You already allow setting depth. You also specify it to a default value. I want to be able to choose that. Does Depth 2 for an object that is nested 5 levels deep is any different than what I requested?

I already showed you the HTML example above. I have a PowerShell module called PSWriteHTML. By default, it uses ConvertTo-HTML which uses depth 0. However, pushing 50k users into HTML makes browsers cry when trying to show it. So I'm using the javascript approach of storing data which prevents autoloading of all 50k rows before displaying them.

image

Since JavaScript is very similar to JSON I'm using ConverTo-JSON to store it within an HTML file. I only require flat JSON. While I guess I could store 5 or 10 or 50 levels deep in there it doesn't make sense for me as I want to display it as a Table (so flat storage). Now imagine 50k adobjects objects each having 5 levels deep of which 4 are useless to display. While the display would still work, the size of the generated HTML would go from 80MB to 120 or 160MB in size. I don't need that.

This is just one use case. A similar use case is used within the PSTeams Powershell module. I sometimes don't want to get 2 levels deep when I require just 0.

Since it takes ages to implement this little change I wrote my own ConvertTo-JSONLiteral which happens to work in PS5+ and allows me to also define how Arrays are treated (for example join them with defined char), how DateTime is converted - for example to a specific format, how numbers are treated, how enums are treated. I got a greater control for display purposes.

While you specifically are thinking JSON use case is very limited I've found that JSON is really similar to JavaScript or CSS with some exceptions or small changes and I use it frequently in ways you would not expect. I don't care if I lose data, as long as I am doing this explicitly.

This change just adds the ability to go from 0 to 100, not from 1-2 to 100. It's trivial, and just fixes something that should have been there from the beginning. The bigger problem is going to remove the default Depth which is set to 2 now, but it's outside of the scope of this change.

< 71D6 input type="hidden" name="_method" value="put" autocomplete="off" />

@iSazonov iSazonov closed this as completed Apr 9, 2021
@iSazonov iSazonov added Resolution-Fixed The issue is fixed. and removed Review - Maintainer The PR/issue needs a review from the PowerShell repo Maintainers labels Apr 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Resolution-Fixed The issue is fixed. WG-Cmdlets-Utility cmdlets in the Microsoft.PowerShell.Utility module
Projects
None yet
Development

No branches or pull requests

5 participants
0