Reputation: 1274
I'm new to elixir and I was trying to pattern match but can't seem to get it right.
I have a decoded variable that has a value of
{:ok,
%{
"_id" => "5b162c483d1f3152b7771a18",
"exp" => 1529286068,
"iat" => 1528422068,
"password" => "$2a$10$hlTl8vV0ENjpRxI1tRVAi.Woxx.na36K/lbZm7FrqLoXfzyoVzFia"
}}
or
{:error, :invalid_token}
and I tried to use if else statement here but its always going to the if statement
if { decoded, :ok } do
IO.inspect(decoded)
else
IO.puts('The token is invalid');
end
Upvotes: 0
Views: 247
Reputation: 383
In elixir, a = 1
does not mean we are assigning 1 to the variable like other programming languages.
The equal sign means we are asserting that the left hand side is equal to the right hand side. It is like basic algebra.
For example,
iex> a =1
1
iex> 1=a
(You can't do that in non-functional language)
1
In your example, you have to match tuples by using pattern matching.
And for your case, you can do with pattern matching and case statement like below.
fine = {:ok,
%{
"_id" => "5b162c483d1f3152b7771a18",
"exp" => 1529286068,
"iat" => 1528422068,
"password" => "pass"
}}
notfine = {:error, :invalid_token}
input = fine # It can be fine or not fine
case input do
#Here do pattern matching with incoming tuple
{:ok,decoded} -> IO.inspect(decoded)
{:error,decoded} -> IO.puts("The token is invalid")
end
Upvotes: 4
Reputation: 121010
Pattern matching has nothing to do with conditional operators, even more, it’s used mostly to avoid using conditional operators which are considered by some of us to be evil.
Pattern matching operator is =
. When you do foo = 42
, you actually pattern match 42 to [yet unbound] foo
variable. That is why the below is perfectly valid:
foo = 42
42 = foo # will succeed!
#⇒ 42
:bar = foo # will raise
# ** (MatchError) no match of right hand side value: 42
Turning back to your example:
ok =
{:ok,
%{
"_id" => "5b162c483d1f3152b7771a18",
"exp" => 1529286068,
"iat" => 1528422068,
"password" => "pass"
}}
ko = {:error, :invalid_token}
value = ok
case value do
{:ok, decoded} ->
IO.inspect decoded, label: "Decoded"
{:error, :invalid_token} ->
IO.puts "Invalid token"
{:error, unknown} ->
IO.inspect unknown, label: "Unknown error"
end
Elixir will go through all the case clauses, trying to pattern match the argument to all the clauses one by one. The very first succeeded will be executed, and the yet unbound variables will be bound (decoded
in the example above.)
Sidenote: Elixir has a great guide and great docs, and one might consider reading it instead of wasting time on unsuccessful attempts and SO questions. Here is a part on pattern matching.
Upvotes: 3