Understanding the forEach container in SPFX

%3CLINGO-SUB%20id%3D%22lingo-sub-2471354%22%20slang%3D%22en-US%22%3EUnderstanding%20the%20forEach%20container%20in%20SPFX%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2471354%22%20slang%3D%22en-US%22%3E%3CP%3EI%20need%20to%20understand%20how%20to%20build%20our%20own%20webparts%20in%20SharePoint%20using%20the%20SharePoint%20Framework.%20I've%20bought%20a%20book%20on%20the%20subject%20and%20have%20been%20trying%20to%20make%20sense%20of%20it.%3C%2FP%3E%3CP%3EI'm%20struggling%20with%20trying%20to%20make%20sense%20of%20sample%20code%20from%20the%20SharePoint%20Development%20with%20SPFX%20by%20Jussi%20Roine%20and%20Olli%20J%C3%A4%C3%A4skel%C3%A4inen%20.%20I%20have%20added%20an%20Interface%20for%20Towns%2C%20created%20mock%20data%20and%20then%20attempted%20to%20consume%20this%20mock%20data%20within%20the%20render()%20function.%3C%2FP%3E%3CP%3EI%20have%20diligently%20copied%20the%20manner%20in%20which%20the%20example%20code%20has%20been%20written.%20I%20created%20the%20Interface%20**ITowns.ts**%20with%20the%20following%20code%3A%3CBR%20%2F%3Eexport%20interface%20ITowns%7B%3CBR%20%2F%3Eid%3Anumber%3B%3CBR%20%2F%3ETitle%3Astring%3B%3CBR%20%2F%3E%7D%3C%2FP%3E%3CP%3EThen%20I%20created%20the%20mock%20data%20file%2C%20which%20I%20called%20**mdfTowns.ts**%20(for%20Mock%20Data%20File)%20with%20the%20following%20code%3A%3CBR%20%2F%3Eimport%20%7B%20ITowns%20%7D%20from%20%22.%2FITowns%22%3B%3CBR%20%2F%3Eexport%20default%20class%20mdfTowns%20%7B%3CBR%20%2F%3Eprivate%20static%20_lstTowns%3AITowns%5B%5D%3D%5B%3CBR%20%2F%3E%7Bid%3A1%2CTitle%3A'Saron'%7D%2C%3CBR%20%2F%3E%7Bid%3A2%2CTitle%3A'Paarl'%7D%2C%3CBR%20%2F%3E%7Bid%3A3%2CTitle%3A'Wellington'%7D%2C%3CBR%20%2F%3E%7Bid%3A4%2CTitle%3A'Gouda'%7D%2C%3CBR%20%2F%3E%7Bid%3A5%2CTitle%3A'Simonsig'%7D%2C%3CBR%20%2F%3E%5D%3B%3CBR%20%2F%3Epublic%20static%20get(restUrl%3Astring%2C%20options%3F%3Aany)%3CBR%20%2F%3E%3APromise%3CITOWNS%3E%7B%3CBR%20%2F%3Ereturn%20new%20Promise%3CITOWNS%3E((resolve)%20%3D%26gt%3B%7B%3CBR%20%2F%3Eresolve(mdfTowns._lstTowns)%3B%3CBR%20%2F%3E%7D)%3B%3CBR%20%2F%3E%7D%3CBR%20%2F%3E%7D%3C%2FITOWNS%3E%3C%2FITOWNS%3E%3C%2FP%3E%3CP%3EIn%20the%20webpart's%20class%20definition%20I%20have%20then%20created%20the%20following%3A%3CBR%20%2F%3E%2F%2FMocking%20Data%20File%20for%20Towns%3CBR%20%2F%3Eprivate%20_getMDFTownsData()%3APromise%3CITOWNS%3E%20%7B%3CBR%20%2F%3Ereturn%20mdfTowns.get(%22%22)%3CBR%20%2F%3E.then((data%3A%20ITowns%5B%5D)%3D%26gt%3B%20%7B%3CBR%20%2F%3Ereturn%20data%3B%3CBR%20%2F%3E%7D)%3B%3CBR%20%2F%3E%7D%3CBR%20%2F%3E%2F%2FGet%20the%20MockData%20from%20the%20ITowns%20interface%3CBR%20%2F%3Eprivate%20_getTownLists()%3A%20Promise%3CITOWNS%3E%20%7B%3CBR%20%2F%3Eif%20(Environment.type%20%3D%3D%3D%20EnvironmentType.Local)%20%7B%3CBR%20%2F%3Ereturn%20this._getMDFTownsData()%3B%3CBR%20%2F%3E%7D%20else%20%7B%3CBR%20%2F%3Ealert%20(%22Todo%20%232%22)%3B%3CBR%20%2F%3Ereturn%20null%3B%3CBR%20%2F%3E%7D%3CBR%20%2F%3E%7D%3C%2FITOWNS%3E%3C%2FITOWNS%3E%3C%2FP%3E%3CP%3ESo%20far%2C%20so%20good%20-%20right%3F%20I%20don't%20get%20any%20errors%2C%20everything%20is%20exactly%20like%20the%20book%20describes.%20I%20even%20went%20so%20far%20as%20to%20embed%20all%20of%20this%20within%20the%20working%20code%20from%20the%20book.%3C%2FP%3E%3CP%3EWithin%20the%20render()%20function%20I%20then%20created%20a%20variable%20to%20hold%20the%20information%20of%20the%20towns%20in%20and%20populated%20it%20with%20data%20from%20the%20mock%20data%20as%20follows%3A%3C%2FP%3E%3CP%3Elet%20l%3A%20string%20%3D%20%22%22%3B%3CBR%20%2F%3Ethis._getTownLists().then(lstTowns%20%3D%26gt%3B%20%7B%3CBR%20%2F%3ElstTowns.forEach(ListedTown%20%3D%26gt%3B%20%7B%3CBR%20%2F%3El%20%2B%3D%20%60%3CBR%20%2F%3E%3CLI%3E%24%7BListedTown.id%7D%20-%20%24%7BListedTown.Title%7D%3C%2FLI%3E%3CBR%20%2F%3E%60%3B%3CBR%20%2F%3E%7D)%3B%3CBR%20%2F%3E%7D)%3B%3CBR%20%2F%3E%3CBR%20%2F%3EI%20then%20render%20this%20as%20follows%3A%3C%2FP%3E%3CP%3Ethis.domElement.innerHTML%20%3D%20%60%3CBR%20%2F%3E%3C%2FP%3E%3CH3%20id%3D%22toc-hId-2061438194%22%20id%3D%22toc-hId-2061438194%22%20id%3D%22toc-hId-2061438194%22%3EList%20items%3C%2FH3%3E%3CBR%20%2F%3E%3CUL%3E%24%7BlistItemsStr%7D%3CBR%20%2F%3E%3CH3%20id%3D%22toc-hId-253983731%22%20id%3D%22toc-hId-253983731%22%20id%3D%22toc-hId-253983731%22%3EList%20of%20Towns%3C%2FH3%3E%3CBR%20%2F%3E***%3CUL%3E%24%7Bl.length%7D***%3CBR%20%2F%3E%60%3B%3CBR%20%2F%3E%7D)%3B%3CBR%20%2F%3E%7D%3CP%3E%3C%2FP%3E%3CP%3EI%20use%20%24%7Bl.length%7D%20to%20count%20the%20number%20of%20towns%20I'm%20supposed%20to%20receive%20because%20%24%7Bl%7D%20on%20its%20own%20returns%20nothing.%3C%2FP%3E%3CP%3EThe%20workbench%20returns%20the%20following%3A%3CBR%20%2F%3EList%20items%3CBR%20%2F%3E1%20-%20First%20list%20item%3CBR%20%2F%3E2%20-%20Second%20list%20item%3CBR%20%2F%3E3%20-%20Third%20list%20item%3CBR%20%2F%3E4%20-%20Fourth%20list%20item%3CBR%20%2F%3E5%20-%20Fifth%20list%20item%3CBR%20%2F%3E6%20-%20Sixth%20list%20item%3CBR%20%2F%3E7%20-%20Seventh%20list%20item%3CBR%20%2F%3E8%20-%20Eight%20list%20item%3CBR%20%2F%3E9%20-%20Ninth%20list%20item%3CBR%20%2F%3E**List%20of%20Towns%3CBR%20%2F%3E0**%3C%2FP%3E%3CP%3EThe%20bold%20section%20(List%20of%20Towns)%20followed%20by%20the%20number%200%20says%20that%20I'm%20doing%20something%20wrong%20-%20but%20I%20don't%20know%20what%20that%20is!%3C%2FP%3E%3CP%3EI'm%20obviously%20not%20understanding%20an%20important%20aspect%20of%20the%20forEach%20loop.%20I'm%20obviously%20doing%20something%20wrong%2C%20but%20the%20book%20doesn't%20help%20at%20all%2C%20and%20I%20cannot%20figure%20out%20how%20this%20should%20work.%3C%2FP%3E%3CP%3EI'm%20including%20the%20webpart%20file%20here%20as%20a%20txt%20file.%3C%2FP%3E%3CP%3EI've%20been%20banging%20my%20head%20against%20this%20for%202%20days%20now%20and%20I%20can't%20see%20what%20I'm%20doing%20wrong.%20Please%20help...%3CBR%20%2F%3E%5B108295-simplepartwebpart.txt%5D%5B1%5D%3C%2FP%3E%3CP%3E%3CBR%20%2F%3E%5B1%5D%3A%20%2Fanswers%2Fstorage%2Fattachments%2F108295-simplepartwebpart.txt%3C%2FP%3E%3C%2FUL%3E%3C%2FUL%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2488108%22%20slang%3D%22en-US%22%3ERe%3A%20Understanding%20the%20forEach%20container%20in%20SPFX%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2488108%22%20slang%3D%22en-US%22%3EHello!%3CBR%20%2F%3E%3CBR%20%2F%3EI%20am%20back%20from%20my%20vacation%20in%20two%20days%20and%20will%20gladly%20look%20into%20it!%3CBR%20%2F%3EPlease%20comment%20on%20this%20thread%20(ping%20me)%20if%20I%20have%20not%20answered%20in%20the%20following%20week.%3CBR%20%2F%3E%3CBR%20%2F%3EYours%20sincerely%2C%3CBR%20%2F%3EAref%20Halmstrand%3C%2FLINGO-BODY%3E
New Contributor

I need to understand how to build our own webparts in SharePoint using the SharePoint Framework. I've bought a book on the subject and have been trying to make sense of it.

I'm struggling with trying to make sense of sample code from the SharePoint Development with SPFX by Jussi Roine and Olli Jääskeläinen . I have added an Interface for Towns, created mock data and then attempted to consume this mock data within the render() function.

I have diligently copied the manner in which the example code has been written. I created the Interface **ITowns.ts** with the following code:
export interface ITowns{
id:number;
Title:string;
}

Then I created the mock data file, which I called **mdfTowns.ts** (for Mock Data File) with the following code:
import { ITowns } from "./ITowns";
export default class mdfTowns {
private static _lstTowns:ITowns[]=[
{id:1,Title:'Saron'},
{id:2,Title:'Paarl'},
{id:3,Title:'Wellington'},
{id:4,Title:'Gouda'},
{id:5,Title:'Simonsig'},
];
public static get(restUrl:string, options?:any)
:Promise<ITowns[]>{
return new Promise<ITowns[]>((resolve) =>{
resolve(mdfTowns._lstTowns);
});
}
}

In the webpart's class definition I have then created the following:
//Mocking Data File for Towns
private _getMDFTownsData():Promise<ITowns[]> {
return mdfTowns.get("")
.then((data: ITowns[])=> {
return data;
});
}
//Get the MockData from the ITowns interface
private _getTownLists(): Promise<ITowns[]> {
if (Environment.type === EnvironmentType.Local) {
return this._getMDFTownsData();
} else {
alert ("Todo #2");
return null;
}
}

So far, so good - right? I don't get any errors, everything is exactly like the book describes. I even went so far as to embed all of this within the working code from the book.

Within the render() function I then created a variable to hold the information of the towns in and populated it with data from the mock data as follows:

let l: string = "";
this._getTownLists().then(lstTowns => {
lstTowns.forEach(ListedTown => {
l += `
<li>${ListedTown.id} - ${ListedTown.Title}</li>
`;
});
});

I then render this as follows:

this.domElement.innerHTML = `
<h3>List items</h3>
<ul>${listItemsStr}</li>
<H3>List of Towns</H3>
***<ul>${l.length}</li>***
`;
});
}

I use ${l.length} to count the number of towns I'm supposed to receive because ${l} on its own returns nothing.

The workbench returns the following:
List items
1 - First list item
2 - Second list item
3 - Third list item
4 - Fourth list item
5 - Fifth list item
6 - Sixth list item
7 - Seventh list item
8 - Eight list item
9 - Ninth list item
**List of Towns
0**

The bold section (List of Towns) followed by the number 0 says that I'm doing something wrong - but I don't know what that is!

I'm obviously not understanding an important aspect of the forEach loop. I'm obviously doing something wrong, but the book doesn't help at all, and I cannot figure out how this should work.

I'm including the webpart file here as a txt file.

I've been banging my head against this for 2 days now and I can't see what I'm doing wrong. Please help...
[108295-simplepartwebpart.txt][1]


[1]: /answers/storage/attachments/108295-simplepartwebpart.txt

2 Replies
Hello!

I am back from my vacation in two days and will gladly look into it!
Please comment on this thread (ping me) if I have not answered in the following week.

Yours sincerely,
Aref Halmstrand

While im "AFK", could you try something for me, in mdfTowns.ts, in row 16, could you bring that row up to 15? So just hit backspace, see images below: 
Before

ArefHalmstrand_0-1624719080553.png

After

ArefHalmstrand_1-1624719095753.png

 

Yours sincerely,
Aref Halmstrand