Reputation: 13862
I am wondering what the best way to tackle down a has many relationship between models in angularjs and with promises. Allow me to show an example, I'd love your feedback on if there could be a better way to implement this.
A Surah
has many Ayahs
My Surah
model:
angular.module('qurancomApp')
.service 'Surah', (Restangular, userOptions, Ayah) ->
class Surah
constructor: (obj) ->
for key of obj
@[key] = obj[key]
getAyahs: (from, to) ->
self = @
@ayahs = Ayah.all
surah_id: @id, from: from, to: to
.then (ayahs) ->
self.ayahs = ayahs
@new: (id)->
return Restangular.one('surahs', id).get().then (data)->
return new Surah(data)
@all: ->
return Restangular.all("surahs").getList()
My Ayah
model:
angular.module('qurancomApp')
.service 'Ayah', (Restangular, userOptions) ->
# AngularJS will instantiate a singleton by calling "new" on this function
class Ayah
constructor: (obj)->
for key of obj
@[key] = obj[key]
@all: (hash) ->
Restangular.one('surahs', hash.surah_id).getList 'ayat',
content: userOptions.content, quran: userOptions.quran, audio: userOptions.audio
.then (data)->
ayahs = data.map (ayah) ->
# The ayah object is returned from Restangular and given all the properties that restangular gives it. For example, you can call
# ayah.save() or ayah.remove() which will make API calls accordingly. This is power and will be perserved when creating the Ayah object
return new Ayah(ayah)
return ayahs
And the corresponding controller:
angular.module('qurancomApp')
.controller 'AyahsCtrl', ($scope, $routeParams, Surah) ->
rangeArray = $routeParams.range.split("-")
Surah.new($routeParams.id).then (surah) ->
$scope.currentSurah = surah
console.log $scope.currentSurah.getAyahs(rangeArray[0], rangeArray[1])
Really, the question is: in the controller, I call function Surah.new()
which then goes ahead and fetches that Surah
from the backend, and then wants to create it's associated Ayahs
, which I inject the Ayah
model into the Surah
model and have a promise on the Ayah
model that is being digested in the Surah
model, within the overall promise of Surah.new()
function.
Is this a correct way to do this? Could there have been a better way?
Upvotes: 2
Views: 78
Reputation: 58531
There could be an argument to make one API call, which returns everything you need, but there are compelling reasons the other way to. There is no general rule. More details about combining API requests here: https://softwareengineering.stackexchange.com/q/252362/20893
Assuming the API is as you have described, there could be advantages in responding to the first call to Surah before loading the Ayahs, but again, there are compelling reasons to do it the other way too.
If there is useful info in Surah that does not rely on Ayahs, you could render it, then each time an Ayah is loaded, also render that into the page (which takes more care to get right in interface, displaying loading spinners where appropriate, handling errors gracefully etc...).
If the info is only useful when loaded in it's entirety, then the way you have it now looks very reasonable to me.
Upvotes: 1