Power FX is the LowCode language of the Power Platform. Originally just for Canvas Power Apps, it's an expression-based language, with a learning curve focused on Excel users. Microsoft has been extended it to other areas of the platform, starting with Private Virtual Agents and Dataverse.
So why would ProCode Developers want to learn it, well as it looks like the language will continue to develop and expand across Microsoft's suite of technology, there's a good chance it will appear in our workstream.
And why would a Power App Developer want to learn JavaScript, well script components use JavaScript and Office Scripts use TypeScript (subset of JavaScript). So, learning JavaScript is a logical progression.
Fizz Buss is a very simple coding exercise, with multiple different ways to deliver the same solution, I thought it would be a great demonstration of the differences and similarities for Power FX and JavaScript.
Well what is Fizz Buzz then:
Fizz buzz is a group word game for children to teach them about division. Players take turns to count incrementally, replacing any number divisible by three with the word "fizz", and any number divisible by five with the word "buzz", and any number divisible by both 3 and 5 with the word "fizzbuzz".
So the requirements would be:
- Increment by one
- If the increment is divisible by 5 print 'fizz'
- If the increment is divisible by 3 print 'buzz'
- Each Increment should be on the sameline
Simple π
For JavaScript I would do
JavaScript
function fizzBuzz(){
const iEnd=100
for(i=1;i<iEnd;i++){
let sPrint="";
if(i % 3==0){sPrint="fizz"};
if(i % 5==0){sPrint+="buzz"};
if(sPrint!=""){console.log(sPrint)};
//console.log(i+"-"+sPrint); use instead above for demo below
}
}
There are 2 small issues for a Power FX comparison, Power FX requires trigger and there is no console so must update somewhere.
We have to change the function to an on click event:
document.getElementById('yourTriggerButton').addEventListener('click', function(){}
And we replace the console.log with
document.getElementById('yourOutput').innerHTML=sPrintAll;
As we are now overwriting not adding to we have to store the previous lines, add the new line, then write to the page.
So it will look like this.
document.getElementById('yourTriggerButton').addEventListener('click', function() {
const iEnd=100
let sPrintAll="";
for(i=1;i<iEnd;i++){
let sPrint="";
let bNewLine=false;
if(i % 3==0){
sPrint="fizz";
bNewLine=true
};
if(i % 5==0){
sPrint+="buzz";
bNewLine=true;
};
if(bNewLine){sPrint+="<br>"};
sPrintAll+=sPrint;
document.getElementById('yourOutput').innerHTML=sPrintAll;
}
});
In Power FX it would be:
//Label Component Text set to sPrint
Collect(arrayI,Sequence(100));
Set(sPrintAll,"");
ForAll(arrayI,
Set(bNewLine,false);
Set(sPrint,"");
If(Mod(Value,3)=0,
Set(sPrint,"Fizz");
Set(bNewLine,true);
);
If(Mod(Value,5)=0,
Set(sPrint,sPrint&"Buzz");
Set(bNewLine,true);
);
If(bNewLine,Set(sPrint,sPrint&Char(10)));
Set(sPrintAll,sPrintAll&sPrint);
)
Well no, that's wrong, ForAll is designed to modifying data, it is scoped to only work with arrays, leveraging Patch etc, not Set.
It is not currently possible to do any looping in Power FX (yep it's a lot more like Excel then JavaScript). To do loops in Power FX you have to leverage the timer component in the canvas app. The parameters would need to be:
OnTimerStart:
Set(bNewLine,false);
Set(i,i+1);
Set(sPrint,"");
If(Mod(i,3)=0,
Set(sPrint,"Fizz");
Set(bNewLine,true);
);
If(Mod(i,5)=0,
Set(sPrint,sPrint&"Buzz");
Set(bNewLine,true);
);
If(bNewLine,Set(sPrint,sPrint&Char(10)));
//Set(sPrint,i&"-"&sPrint&Char(10)); as shown in demo video
Set(sPrintAll,sPrintAll&sPrint);
If(i>=100,Set(bStart,false)
Repeat: bStart
Duration: 10
Start: bStart
- Set to true by a start button
Label Component Text: sPrint
Unfortunately, that means we are now not aligned with the JavaScript code we have written, as we have the equivalent of a timer in JavaScript.
We move our code from inside a for loop to inside setInterval, which is almost the same as the timer component
const timer=setInterval(function(){ },10)
And to stop the timer we use
clearInterval(timer)
document.getElementById('yourTriggerButton').addEventListener('click', function() {
let i=1;
let sPrintAll="";
const timer=setInterval(function(){
let sPrint="";
let bNewLine=false;
if(i % 3==0){
sPrint="fizz";
bNewLine=true
};
if(i % 5==0){
sPrint+="buzz";
bNewLine=true;
};
if(bNewLine){sPrint+="<br>"};
sPrintAll+=sPrint;
document.getElementById('yourOutput').innerHTML=sPrintAll;
i++;
if(i==100){clearInterval(timer)}
}, 10);
});
Although the syntax's are different they are close enough, the bigger challenge switching between them is the differences in structure. Power FX, like most LowCode, relies on pre built components. The code is then layered on top. JavaScript, particularly with libraries is the same, but with the components layered on top of the code. JavaScript allows you to build your own when there is a gap and have the best of both worlds, which makes sense as to why Microsoft allows you to build custom components in JavaScript.
Interesting call out I spotted, although the term LowCode is often presumed as less code, it isn't necessarily is. When like for like it generally is, but a more direct/shorter solution can often be found in ProCode.
Solution | Line Count |
---|---|
JavaScript | 7 |
Power FX | 12 |
JavaScript like for like | 18 |
I often think of it like binary, because it has only 2 values it could be thought of as simpler, but that simplicity makes complexity increases exponentially, equaling longer code e.g. 99 in binary is 1100011.
Note:
- Local variables in Power Apps are scoped to the screen, JavaScript are function scoped
- Power FX can also use '!' for not equal to, '&&' for And, '||' for Or
Furter Reading
Top comments (0)