Ramda error with compose and reduce > Cannot read property '##transducer/step' of undefined - ramda.js

I have a strange error (for me) with Ramda:
When I use in a composition:
const total_ok = R.compose(
values => R.reduce(sum_value, 0)(values),
R.prop('items')
)
all work fine.
But if I refactor it like that:
const total_bad = R.compose(
R.reduce(sum_value, 0),
R.prop('items')
)
I have the error "Cannot read property '##transducer/step' of undefined".
I don't understand why.
You can test the code here: http://ramdajs.com/repl/#?code=const%20total_ok%20%3D%20R.compose%28%0A%20%20values%20%3D%3E%20R.reduce%28sum_value%2C%200%29%28values%29%2C%0A%20%20R.prop%28%27items%27%29%0A%29%0A%0Aconst%20total_bad%20%3D%20R.compose%28%0A%20%20R.reduce%28sum_value%2C%200%29%2C%0A%20%20R.prop%28%27items%27%29%0A%29%0A%0Aconst%20sum_value%20%3D%20%28duration%2C%20item%29%20%3D%3E%20%7B%0A%20%20return%20duration%20%2B%20item.value%3B%0A%7D%3B%0A%0A%0Alet%20data%20%3D%20%7B%0A%20%20items%3A%20%5B%0A%20%20%20%20%7B%0A%20%20%20%20%20%20value%3A%201%0A%20%20%20%20%7D%2C%0A%20%20%20%20%7B%0A%20%20%20%20%20%20value%3A%202%0A%20%20%20%20%7D%2C%0A%20%20%20%20%7B%0A%20%20%20%20%20%20value%3A%203%0A%20%20%20%20%7D%0A%20%20%5D%0A%7D%0A%0Aconsole.log%28%22total%28data%29%3A%20%22%2Btotal_ok%28data%29%29%3B%0Aconsole.log%28%22total%28data%29%3A%20%22%2Btotal_bad%28data%29%29%3B
Have you an idea?
Frédéric

This is simply because you're trying to use sum_value before you define it. When you introduce the lambda expression, values => R.reduce(sum_value, 0)(values), you delay the evaluation of sum_values until after you've defined it, and everything works.
If you were to move the definition of sum_value above total_bad (or similarly if it were a function declaration or a var statement, and therefore hoisted) then this would just work.
You can see an updated version in the REPL.

Related

Vue: (Marvel API) Error in render: "TypeError: Cannot read property 'path' of undefined"

As mentioned, I'm using the Marvel API. At mounted() I use this action:
mounted() {
this.$store.dispatch("get/getCharacter", this.$route.params.id);
},
This uses axios to call for the character object, and sends that payload to a mutation, which updates the state of character: {}. I use a getter to call the state of the character to output in my page. Everything works, the image appears and if I interpolate the string to the page, that appears as it should. However, I'm still getting the typeError. I'm creating the img like this:
<img :src="`${character.thumbnail.path}/portrait_incredible.${character.thumbnail.extension}`
So, doing this {{ character.thumbnail.path }} outputs the correct 'path' string from the object. The image loads perfectly on my computer too, but not on my Oppo phone (I've uploaded it to Netlify to check). Strangely, my friends iPhone does load the images using the Netflify link.
What am I doing wrong, and how can I make this error go away?
Thanks for any help!
I know this question is old, but I would like to give my solution since no one has answered this question. So it may help someone in future.
You can use the optional chaining operator to solve this,
The ?. operator is like the . chaining operator, except that instead of causing an error if a reference is nullish (null or undefined), the expression short-circuits with a return value of undefined. When used with function calls, it returns undefined if the given function does not exist.
See Optional chaining (?.)
character.thumbnail?.path
character.thumbnail?.extension

How to create a function that delays call to given function?

Using ramda, I'm trying to find (or build) a very trivial operator that expects a function and returns a function that asks for its arguments before returning a new function that makes the actual call. You can think of this as "delaying" the invocation. As pointed out by replies below, this is usually call a thunk.
Essentially,
const wrap = fn => (...args) => () => fn(...args);
const sayHiWorld = wrap(console.log)('hi', 'world');
sayHiWorld();
// -> 'hi world'
Partial application won't work in my case because args are actually not known at moment of definition. Closest I got was by using R.useWith - but that restricts the number of arguments.
Any ideas?
I'm a little confused. It looks as though you have a perfectly good version here in your wrap. Are you expecting that Ramda must already have that? Do you want a version of it written with Ramda?
What you want to create with a call to this function is often known as a thunk, and I've sometimes seen such a function called thunkify. But wrap is fine too.
You might see the discussion here too.

Aurelia transpiler: "this" is "null"

I have the following code in my Aurelia app:
import {digit} from "../util/random" // generates a random digit [0,9]
export class UnitedStates {
zipCode() {
return ""+digit(5);
};
zipPlus4() {
return this.zipCode()+"-"+digit(4);
};
...
}
Getting the error TypeError: Cannot read property 'zipCode' of null on the body of zipPlus4. Inspection in the developer tool reveals that this is null.
Why is this null, and how do I fix this?
This is an issue with the transpiler. Recall that the arrow function notation maintains lexical this (or read here for more). So, when Babel and other transpilers enter a new scope, they maintain a local this variable so that it will be accessible from any child scopes. Usually, this variable is _this.
Sometimes, debuggers like DevTools have a hard time understanding the sourcemaps, and they report a null this. Turns out, this is only when inspecting the code; when running the code, it works properly.
So how do you inspect the value of this when it is reported to be null? Inspect _this, usually from the console. That will give you the true this value that is being used.

Reuse the description of an existing Error when creating a new Error

I have the following code in Rust, which does not compile, but shows the intent of what I'd like to do.
pub fn parse(cursor: &mut io::Cursor<&[u8]>) -> io::Result<Ack> {
use self::byteorder::{BigEndian, ReadBytesExt};
use self::core::error::Error;
match cursor.read_u16::<BigEndian>() {
Err(byteorder::Error::Io(error)) => Err(error),
Err(error) =>
Err(io::Error::new(io::ErrorKind::Other, error.description(),
None)),
Ok(value) => Ok(Ack { block_number: value })
}
}
Essentially, I want to take the error description of an error returned by the byteorder library and use it to create the description of an error I'll pass back to the user of my library. This fails with packets.rs:166:58: 166:63 error:errordoes not live long enough, and I understand why.
The byteorder library solves this issue by wrapping an std::io::Result in the byteorder::Error::Io constructor. However, I don't want to take this route because I'd have to define my own error type that wraps either an std::io::Error or a byteorder::Error. It seems to me that my users shouldn't know or care that I use the byteorder library, and it shouldn't be part of my interface.
I'm a Rust newbie and don't yet know the idioms and best practices of the language and design. What are my options for dealing with this?
Your problem is in fact in that io::Error::new()'s second parameter is &'static str, while byteorder::Error::description() returns a &'a str where 'a is lifetime of the error object itself which is less than 'static. Hence you can't use it for io::Error's description.
The simplest fix would be moving byteorder::Error description to detail field of io::Error:
Err(error) =>
Err(io::Error::new(
io::ErrorKind::Other,
"byteorder error",
Some(error.description().to_string())
)),
However, you should seriously consider making a custom wrapper error type which encapsulates all "downstream" errors. With properly written FromError instances you should be able to write something like
try!(cursor.read_u16::<BigEndian>()
.map(|value| Ack { block_number: value }))
instead of your whole match. Custom error wrappers will also help you when your program grows and more "downstream" error sources appear - you could just add new enum variants and/or FromError implementations to support these new errors.
I cannot test your code so I can't be sure. Isn't the ref keyword enough?
Err(byteorder::Error::Io(ref error)) => Err(error),

In VB6, how do I call a COM object requiring a pointer to an object?

I'm having trouble with a .NET Assembly that is com visible, and calling certain methods from VB6.
What I have found is that if the parameters are well defined types, (e.g. string), calls work fine. If they are higher level objects, it raises a runtime error '438' suggesting that the property or method is not present. I suspect that this is a question of having the correct signature on the call, but I can't see how to do this correctly.
I believe that I've done everything correct on the .NET side (ComVisible, public interfaces, etc. and even have it down to a simple enough case).
Looking at the output from the typelib viewer, I have the following:
dispinterface ISimple {
properties:
methods:
[id(0x60020000)]
void Add([in] ISimpleMember* member);
[id(0x60020001)]
ISimpleMember* Create();
};
OK. So I have 2 methods in my ISimple interface. One takes an ISimpleMember (Add), whilst the other, returns an ISimpleMember.
The corresponding code in VB looks like this:
Dim item As ISimpleMember
Dim simple As simple
Set item = New SimpleMember
item.S1 = "Hello"
item.S2 = "World"
Set simple = New simple
simple.Add (item) <---- This raised the run time error 438
Set item = simple.Create <---- This works fine, returning me an ISimpleMember
I've tried a couple of things:
1. Dim item as SimpleMember (makes no difference)
2. simple.Add(ObjPtr(item)) - Syntax error
3. simple.Add(ByRef item) - Syntax error
Basically, The run time error is the same as if I had
simple.AMethodThatIHaventWritten()
Also, If I browse References in the VB6 Environment, The Add method is well defined:
Sub Add(member As SimpleMember)
I've found the answer I believe. It was very simple:
When calling a SubRoutine, I shouldn't put the name in braces. the call should have been:
simple.add member
rather than
simple.add(member)
If I change it to a function (i.e. return a value rather than void) the braces are necessary
This seems to work
(Probably) The top 3 VB6 coding mistakes made by devs who now mainly code in C#, Javascript etc. Are:-
Placing ; at the end of lines. Its a syntax error very easily spotted and picked up the compiler.
Not placing Then on the other side of an If condition expression. Again its a syntax error.
Calling a method without retrieving a value and yet using ( ) to enclose the parameter list. With multiple parameters this is a syntax error and easily found. With only one parameter the use of ( ) is interpreted as an expression. Its the result of the ( ) expression which is passed as parameter. This causes problems when ByRef is expected by the callee.