Empty string and nullable string
Nullable string has three states on a frontend code
Some programming languages allow us to have a nullable string value. On a frontend code, developers may have to consider the three states for a nullable string:
- The value is
null
- The value is a type of string, but it's empty
- The value is a type of string, and its length is more than
0
On a frontend code, developers usually make the script render HTML elements in accordance with provided values from its
server-side. When a value is null
, a component will be rendered with "No value is set." Also, it may display the same
message if the value is empty. Of course, the null
and an empty string are completely different, but practically, it
makes sense to deal with them the same way when presenting the value on a page. So, it's not sufficient to just detect
whether a passed value is null
or not on a frontend code, and frontend developers must check whether the value is empty.
Perhaps, if the null
and an empty string are virtually the same, the server-side should change its API to return a
string value: non-nullable string because a nullable string is redundant.
Is a nullable string always overkill?
If separated teams maintain a server-side and a frontend respectively, server-side developers don't have to care about a
case in which an empty string should be handled differently from null
. Rather, they should not think about it. Their
concern is only whether a value is string or null
. They are not aware that an empty string has a special meaning. If
frontend developers and server-side developers shared this meaning, this value could be a string, not a nullable string.
However, both sides will have to share a prerequisite that an empty string is special, and some documentation may be
required. There would be no problem as long as the different teams can maintain this information continuously.
However, it would not be easy for server-side developers who have just joined the team to understand the special
meaning. They might wonder why they have to set an empty string. They might think it should be null
because the value
is not unset.
On the other hand, a nullable string is obvious and understandable for many server-side developers, even for newcomers.
Example
Let's take a look at one example.
Server-side code will respond with this data type:
interface User {
id: number,
name: string,
bio: string | null,
}
Meanwhile, frontend code will handle the data like this:
const user: User = await fetch('/users/123')
if (user.bio != null && user.bio.length > 0) {
console.log(`${user.name}'s bio is ${user.bio}`)
} else {
console.log(`${user.name}'s bio is unset.`)
}
As I described above, the frontend deals with the empty bio
as the same as null
. If the bio
in User
were string,
the frontend code could be updated simply:
const user: User = await fetch('/users/123')
-if (user.bio != null && user.bio.length > 0) {
+if (user.bio.length > 0) {
console.log(`${user.name}'s bio is ${user.bio}`)
} else {
console.log(`${user.name}'s bio is unset.`)
And then, if frontend developers want to code without checking whether it's null
, they have to share the information
that the bio
must be empty if it's unset.
Note I'm not discussing runtime checking. This code might still require user.bio != null
because the data from the
server-side is still uncertain in a runtime environment — it means data from the server-side is any
.
Wrap up
A nullable string may force developers to code more with an extra check. If you want to remove it, you may have to share a specific state on a value among other developers — e.g., a case that an empty string is special.