question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unable to get empty value from nullable instance like TextPrompt<Uri?>

See original GitHub issue

I want to get AbsoluteUri or null but it’s not supported by TextPrompt even with AllowEmpty=true.

var uri = await new TextPrompt<Uri?>( $"abc" )
    .AllowEmpty()
    .Validate( value =>
    {
        if ( !( value?.IsAbsoluteUri ?? true ) )
            return ValidationResult.Error( "[red]It must be absolute url[/]" );
        return ValidationResult.Success();
    } )
    .ShowAsync( AnsiConsole.Console, CancellationToken.None );

If I press enter then I get “Invalid input”.

I suppose that input is string.Empty when we call TryConvertFromString. UriConverter allow to convert from string.Empty and return null. In that case condition in line 146 in TextPrompt should be modified and allow result to be null if conversion was successfull.

else if (!TypeConverterHelper.TryConvertFromString<T>(input, out result) || result == null && Nullable.GetUnderlyingType(typeof(T)) == null)
//or maybe
else if (!TypeConverterHelper.TryConvertFromString<T>(input, out result))

This issue could happen for other types if allow to convert from string.Empty and return null. What do you think?

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
nils-acommented, Nov 22, 2022

@danielklecha simply removing that || result == 0 will open a long bunch of nullable issues. So, I feel it’s not as easy as that. Also, that would be a breaking change, so we’d need to think about that.

We’re certainly open to suggestions, though.

/cc @iraklikhitarishvili - this answers your question in #998, probably.

1reaction
nils-acommented, Feb 9, 2022

The “problem” is the || result == null in

https://github.com/spectreconsole/spectre.console/blob/0bbf9b81a9a0e5b4a2c4d3e0aab253cf7e13f247/src/Spectre.Console/Widgets/Prompt/TextPrompt.cs#L147

This makes TypeConverters that return null values (like the UriTypeConverter) yield “invalid” results.

I feel this is a bug. E.g. given the following really far-fetched example:

using System.ComponentModel;
using System.Globalization;
using Spectre.Console;

var thing = await new TextPrompt<Thing>("thing")
    .AllowEmpty()
    .ShowAsync(AnsiConsole.Console, CancellationToken.None);
if (thing == null)
    AnsiConsole.WriteLine("You selected a null value");
else
    AnsiConsole.WriteLine($"You selected {thing.Content}");


[TypeConverter(typeof(ThingConverter))]
public class Thing
{
    public Thing(string content)
    {
        Content = content;
    }

    public string Content { get; }
}


public class ThingConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
    {
        if (sourceType == typeof(string))
        {
            return true;
        }

        return base.CanConvertFrom(context, sourceType);
    }

    public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
    {
        if (value is string strVal)
        {
            if (string.IsNullOrEmpty(strVal))
            {
                return null;
            }

            if (strVal.EndsWith("a"))
            {
                return null;
            }

            return new Thing(strVal);
        }

        return base.ConvertFrom(context, culture, value);
    }
}

The TypeConverter returns null for all strings ending in a. (As I said: Really far-fetched…) So an (IMHO) valid input of “trallala” would result in an “invalid input” message.

Read more comments on GitHub >

github_iconTop Results From Across the Web

The parameter can't have a value of 'null' because of its ...
In the function and the constructor, these values might be null when the function is called without the named parameter: calculate() or Foo()...
Read more >
Dart Null Safety: The Ultimate Guide to Non-Nullable Types
A complete tour of Null Safety & non-nullable types, the syntax changes they introduce in Dart 2.12, and how to use them in...
Read more >
Understanding null safety
The null value is an instance of the Null class, and Null has no “length” getter. ... They have no methods and you...
Read more >
Why nullable types?. Null in Dart code indicates that a…
One option is to say that a variable can contain a value of the expected type, or it can contain the magic value...
Read more >
Dart Null Safety - Assign a nullable value to a non ... - YouTube
In this video we look at assigning nullable values to a non- nullable variable by using the assertion operator (!). We alse learn...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found