<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Siyu on Medium]]></title>
        <description><![CDATA[Stories by Siyu on Medium]]></description>
        <link>https://medium.com/@siyuduan.learning?source=rss-70765711682e------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*q7NOjly_xNTmLrFJz8XEng.jpeg</url>
            <title>Stories by Siyu on Medium</title>
            <link>https://medium.com/@siyuduan.learning?source=rss-70765711682e------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 18 May 2026 06:28:52 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@siyuduan.learning/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Angular | Directives vs Components]]></title>
            <link>https://medium.com/@siyuduan.learning/angular-directives-vs-components-ca55f77132c7?source=rss-70765711682e------2</link>
            <guid isPermaLink="false">https://medium.com/p/ca55f77132c7</guid>
            <category><![CDATA[components]]></category>
            <category><![CDATA[angular-directive]]></category>
            <category><![CDATA[angular]]></category>
            <category><![CDATA[angular-basics]]></category>
            <category><![CDATA[code-example]]></category>
            <dc:creator><![CDATA[Siyu]]></dc:creator>
            <pubDate>Wed, 04 Feb 2026 20:06:01 GMT</pubDate>
            <atom:updated>2026-02-04T20:06:01.037Z</atom:updated>
            <content:encoded><![CDATA[<p><em>*Learning notes for Udemy course (Angular — The Complete Guide, Section 7 by Max)</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8KSKMFRPwZUfpbZiku2P4g.png" /></figure><h3>Directives and Components</h3><ul><li>Directives are ‘enhancements’ for elements.</li><li>They can change the configuration (properties, attributes), styling, or behaviour of elements.</li><li>Directives don’t have templates (this is the main differences with components — Components are Directives with a template).</li></ul><h3>Two types of Directives: Attribute Directive, Structural Directive</h3><h4><strong>Attribute Directives</strong></h4><pre>// Directives that changes attribute.<br>&lt;input type=&quot;email&quot; name=&quot;email&quot; [(ngModel)]=&quot;email&quot; /&gt;</pre><h4><strong>Structural Directives</strong></h4><ul><li>shortand structural directives: e.g. *ngIf, *select’.</li><li>can only apply one structural directive per element when using the shorthand syntax.</li><li>&lt;ng-container&gt; can be used when to create wrapper layers when multiple structural directives need to be applied around the same physical DOM element or component, which allows the user to define the nested structure.</li></ul><pre>// Directives that changes DOM.<br>&lt;p *ngIf=&quot;isActive&quot;&gt;Show this line when the status is active.&lt;/p&gt;</pre><pre>// np-template by default is not rendered, it would render when appAuth is user in the following example<br>// Structural Directive and Syntactic Sugar can be used interchangeably<br>&lt;ng-template appAuth=&quot;user&quot;&gt;<br>  &lt;p&gt;Welcome!&lt;/p&gt;<br>&lt;/ng-template&gt;<br><br>// alternative<br>&lt;p *appAuth=&quot;user&quot;&gt;Welcome!&lt;/p&gt;</pre><h3>Build-in Directives and Custom Directives</h3><h4><strong>Build-in Directives</strong></h4><p>When using ngModel in Forms, in dev-tool, we can see classes with ‘ng’ prefiexes added to this element.</p><pre>// ngModel here is a build-in directive<br>&lt;input name=&quot;title&quot; ngModel /&gt;<br><br><br>// ngModel can be used with two-way binding <br>&lt;input type=&quot;email&quot; name=&quot;email&quot; [(ngModel)]=&quot;email&quot; /&gt;</pre><h4><strong>Custom Directives</strong></h4><ul><li>We can create custom attribute directives, and custom structural directives.</li><li>Custom directives are way less than components been used in a project.</li></ul><h4><strong>Custom Directives Example (highlight content on mouse hover)</strong></h4><ol><li>create custom directive file</li></ol><pre>// highlight.directive.ts<br><br>import { Directive, ElementRef, inject } from &#39;@angular/core&#39;;<br><br>@Directive({<br>  selector: &#39;[appHighlight]&#39;,<br>  host: {<br>    &#39;(mouseenter)&#39;: &#39;onMouseEnter()&#39;,<br>    &#39;(mouseleave)&#39;: &#39;onMouseLeave()&#39;,<br>  }<br>})<br>export class HighlightDirective {<br>  elementRef = inject(ElementRef);<br><br> onMouseEnter() {<br>    this.highlight(&#39;gold&#39;);<br>  }<br>  onMouseLeave() {<br>    this.highlight(&#39;&#39;);<br>  }<br>  private highlight(color: string) {<br>    this.elementRef.nativeElement.style.backgroundColor = color;<br>  }<br>}</pre><p>2. import created directive in component ts file, and implement in the target code section</p><pre>import {Component, input} from &#39;@angular/core&#39;;<br>import { Movie } from &#39;../model/movie.model&#39;;<br>import { HighlightDirective } from &quot;../highlight.directive&quot;; //import custom directive<br><br>@Component({<br>  selector: &#39;app-movie-item&#39;,<br>  template: `<br>    &lt;div class=&quot;movie-item&quot; appHighlight&gt; //implement<br>      &lt;div&gt;<br>        &lt;h4&gt;{{ movie().title }}&lt;/h4&gt;<br>        &lt;small class=&quot;subtitle&quot;&gt;<br>          &lt;span&gt;Release date: {{ movie().release_date }}&lt;/span&gt;<br>          &lt;span&gt;Budget: $ {{ movie().budget }} million&lt;/span&gt;<br>          &lt;span&gt;Duration: {{ movie().duration }} min&lt;/span&gt;<br>        &lt;/small&gt;<br>      &lt;/div&gt;<br>      &lt;button&gt;Details&lt;/button&gt;<br>    &lt;/div&gt;<br>  `,<br>  styleUrls: [ &#39;movie-item.component.scss&#39; ],<br>  imports: [HighlightDirective] //add as imports<br>})<br>export class MovieItemComponent {<br>  movie  = input.required&lt;Movie&gt;();<br>}</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ca55f77132c7" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Angular Quick Example: passing down data from parent component to child component using input()]]></title>
            <link>https://medium.com/@siyuduan.learning/angular-quick-example-passing-down-data-from-parent-component-to-child-component-using-input-5d0044438294?source=rss-70765711682e------2</link>
            <guid isPermaLink="false">https://medium.com/p/5d0044438294</guid>
            <category><![CDATA[angular]]></category>
            <category><![CDATA[angular-basics]]></category>
            <category><![CDATA[fundamentals]]></category>
            <category><![CDATA[angular-fundamentals]]></category>
            <dc:creator><![CDATA[Siyu]]></dc:creator>
            <pubDate>Thu, 15 Jan 2026 20:36:50 GMT</pubDate>
            <atom:updated>2026-01-16T08:33:16.549Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="Image with text of ‘Angular Quick Examples’" src="https://cdn-images-1.medium.com/max/1024/1*eowUsEYg2Kebnqc4bzCUVg.png" /></figure><blockquote>Key words: input(), one-way data flow, parent to child component;</blockquote><blockquote>Doc: <a href="https://angular.dev/guide/components/inputs">Accepting data with input properties • Angular</a></blockquote><h3>Mental Model</h3><p><em>drinks-list</em> is parent component, <em>drink-item</em> is child component.</p><pre>// component structure<br><br>drinks-list<br>  drink-item<br>  --drink-item.html<br>  --drink-item.scss<br>  --drink-item.ts<br>--drinks-list.htm<br>--drinks-list.scss<br>--drinks-list.ts</pre><p>Use <strong>property binding</strong> to take the value of drink from parent component, and pass it into the child component’s drinkData input. drink exist in parent component’s TS file.</p><p>Parent component own the data, child component using the data through input(). This is a one-way data flow.</p><p>Latest vs Older version:</p><pre>export class DrinkItemComponent {<br>  // latest signal-based input() function<br>  drinkData = input&lt;Drink&gt;();<br><br>  // older decorator-based @Input() <br>  @Input() drinkData: Drink;<br>}</pre><h3>Code Example</h3><p><em>Parent component:</em></p><pre>// drinks-list.html<br><br>&lt;div class=&quot;container&quot;&gt;<br>  &lt;app-drink-item [drinkData]=&quot;drink&quot;/&gt;<br>&lt;/div&gt;</pre><p><em>Child component:</em></p><pre>// this is HTML and TS in child component<br><br>import { Component, input } from &#39;@angular/core&#39;;<br>import { Drink} from &#39;../model/drink.model&#39;;<br><br><br>@Component({<br>  selector: &#39;app-drink-item&#39;,<br>  template: `<br>    &lt;div class=&quot;drink-item&quot;&gt;<br>      &lt;div&gt;<br>        &lt;h3&gt;{{ drinkData()?.title }}&lt;/h3&gt;<br>        &lt;small class=&quot;subtitle&quot;&gt;<br>          &lt;span&gt;Brand: {{ drinkData()?.brand }}&lt;/span&gt;<br>          &lt;span&gt;Size: {{ drinkData()?.size+ &#39; ml&#39;}}&lt;/span&gt;<br>          &lt;span&gt;Price: {{ &#39;£&#39; + drinkData()?.price}}&lt;/span&gt;<br>        &lt;/small&gt;<br>      &lt;/div&gt;<br>      &lt;button&gt;Details&lt;/button&gt;<br>    &lt;/div&gt;<br>  `,<br>  styleUrls: [&#39;drink-item.component.scss&#39;]<br>})<br><br>export class DrinkItemComponent {<br>  drinkData = input&lt;Drink&gt;();<br>}</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5d0044438294" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How teamwork helped me survive Bootcamp Week 4 — — build a RESTful API]]></title>
            <link>https://medium.com/@siyuduan.learning/how-teamwork-helped-me-survive-bootcamp-week-4-build-a-restful-api-a6e02ded886a?source=rss-70765711682e------2</link>
            <guid isPermaLink="false">https://medium.com/p/a6e02ded886a</guid>
            <category><![CDATA[bootcamp]]></category>
            <category><![CDATA[api]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[learning-to-code]]></category>
            <category><![CDATA[full-stack-development]]></category>
            <dc:creator><![CDATA[Siyu]]></dc:creator>
            <pubDate>Tue, 07 Nov 2023 21:57:05 GMT</pubDate>
            <atom:updated>2023-11-07T22:38:03.257Z</atom:updated>
            <content:encoded><![CDATA[<h3>How teamwork helped me survive Bootcamp Week 4 — — build a RESTful API</h3><p>Recognising the power of teamwork</p><figure><img alt="An illustration of a team of three." src="https://cdn-images-1.medium.com/max/1024/1*7rCFVbR8tc8nPJkAn1bGaw.png" /></figure><p>I started SoC at the beginning of Sep 2023. In week 4 we built a RESTful API for our Friday hackathon. These are some of the topics we learned in the first four weeks:</p><ul><li>Week 1: learning how to learn, computational thinking, Git&amp;GitHub, agile methodology</li><li>Week 2: JavaScript — loops, function &amp; scope, arrays, objects</li><li>Week 3: Front-end — DOM, debug, event, navigating data, fetch API</li><li>Week 4: Back-end — Node.js, npm, CRUD functionality, Express.js, RESTful API</li></ul><p>The Hackathon Fridays are typically conducted as follows: In the morning, we receive the project brief, and then using the knowledge we have learned (mainly from the current week), work together as a team on the project. At the end of the day, we present our work to coaches and peer bootcampers.</p><h3>Our Team’s CountryInfo API Project</h3><p>After receiving the project brief on Friday morning, we agreed to spend ten minutes reading through the brief individually. Then, we came back together to discuss our understanding of the project, and how we wanted to plan the project and use our time.</p><h4><strong>Planning</strong></h4><p>As we all came from different countries, we decided to choose to create a database with information of different countries. We used draw.io to create this flowchart, which helped us to virtualize tasks step by step and which file we should create and work on in each step.</p><figure><img alt="A flowchart about the planning of the week 4 project" src="https://cdn-images-1.medium.com/max/702/1*CjyOwQJaaQg3I6aAE00T0Q.jpeg" /></figure><h4><strong>Data</strong></h4><p>Our data is stored in a JSON file. Thanks to my teammates and their master skills in using ChatGPT, we quickly filled our database with all the information we wanted for Spain, China, India, the UK, Switzerland and Japan. The following piece of code shows the JSON data structure we stored for each country.</p><pre>[<br>  {<br>    &quot;country&quot;: &quot;United Kingdom&quot;,<br>    &quot;capitalCity&quot;: &quot;London&quot;,<br>    &quot;id&quot;: &quot;c68240be-36f9-4ba7-80da-2a94462df95d&quot;,<br>    &quot;placesOfInterest&quot;: {<br>      &quot;Edinburgh_Castle&quot;: &quot;It is a historic fortress that dominates the skyline of Edinburgh&quot;,<br>      &quot;Stonehenge&quot;: &quot;One of the most famous prehistoric monuments in the world, located in Wiltshire&quot;,<br>      &quot;Giant_Causeway&quot;: &quot;A natural wonder and UNESCO World Heritage Site located in Northern Ireland&quot;<br>    }<br>  }<br>  ...<br>]</pre><h4>Demo</h4><p>Here we use the VSCode extension Thunder Client to test our API endpoints. A list of all the endpoints we created are listed as follows:</p><figure><img alt="RESTful API endpoint list: GET, POST, DELETE" src="https://cdn-images-1.medium.com/max/1024/1*4kCo0jhdLxCpkOuULiu1FQ.jpeg" /></figure><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FxxDdSYEzDP4%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DxxDdSYEzDP4&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FxxDdSYEzDP4%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="640" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/afc29b6bf8712a469fa115abf4e20577/href">https://medium.com/media/afc29b6bf8712a469fa115abf4e20577/href</a></iframe><h3><strong>Teamwork Challenges in Coding Bootcamp</strong></h3><p>Each week we switch team members on Monday. We started by saying goodbye to last week’s team members, we were then assigned to a new group (two or three people).</p><p><em>“Monday is the hardest.” </em>Exactly, I remembered hearing this from one peer bootcamper on a discussion session. And it resonated strongly with me. The anxiety of establishing a rapport with new people. The unknowns of new topics/knowledge of the coming week. The uncertainty about whether we, as a team, can effectively learn new knowledge together and face challenges.</p><p><em>“…I’m not sure about that, could we try something different?” </em>Dealing with different ideas sometimes can be hard. Especially when the team was given a limited amount of time and worked on challenging tasks.</p><h3><strong>What I learned from this week’s collaborative working</strong></h3><p>Give everyone time to get to know each other and understand how other people learn and work. Each of us has different studying and working habits. Some people like to express their thoughts while they’re thinking, while others prefer to think first and then speak.</p><p>I think through these weeks’ of studying and working with different people, my biggest takeaway is — — it doesn’t matter how different we are (in terms of preferred ways of learning and working), as long as we communicate well, stay positive, and working towards the same goal, we can always achieve results that exceed our expectations.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a6e02ded886a" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>